Generering av konfigurationer för nginx, historik för en pull-begäran

Hälsningar, kamrater. Vackert på mina stridsservrar nginx har körts sedan 2006 och under åren av dess administration har jag samlat på mig många konfigurationer och mallar. Jag berömde nginx mycket och på något sätt visade det sig att jag till och med startade en nginx hub på navet också, visa upp m/
Vänner bad mig att skapa en utvecklingsgård åt dem, och istället för att dra dem mina specifika mallar, kom jag ihåg ett intressant projekt nginxconfig.io, som sprider konfigurationer på hyllorna och förbereder allt för låter kryptera osv. Jag tänkte, varför inte? Jag blev dock irriterad över det faktum att nginxconfig erbjuder mig att ladda ner zip-arkivet till webbläsaren, utan att tillåta mig att ladda upp det direkt till servern med wget/fetch/curl. Vilket nonsens, varför behöver jag det i webbläsaren, jag behöver det på servern från konsolen. Arg gick jag till github för att se hur projektet är, vilket ledde till dess gaffel och, som ett resultat, en pull-förfrågan. Som jag inte skulle skriva om om det inte var intressant 😉

Generering av konfigurationer för nginx, historik för en pull-begäran

Naturligtvis, innan jag grävde i källorna, tittade jag på var Chrome hämtar det genererade zip-arkivet med konfigurationer, och där väntade en adress som börjar med "blob:" på mig, oj. Det har redan blivit tydligt att tjänsten inte genererar något på vägen, i själva verket görs allt av js. Faktum är att zip-arkivet genereras av klienten, webbläsaren och javascriptet själv. De där. skönheten är att projektet nginxconfig.io kan enkelt sparas som en HTML-sida, laddas upp till vissa narod.ru och det kommer att fungera) Detta är en väldigt rolig och intressant lösning, men det är fruktansvärt obekvämt för att ställa in servrar, faktiskt exakt för det som detta projekt skapades. Ladda ner det genererade arkivet med en webbläsare och överför det sedan till servern med nc... 2019? Jag satte mig i uppgift att hitta ett sätt att ladda ner den resulterande konfigurationen direkt till servern.
Efter att ha lagt upp projektet började jag fundera på vad mina alternativ var. Uppgiften komplicerades av att jag inte ville frångå villkoret att projektet skulle förbli en ren front-end, utan någon back-end. Naturligtvis skulle den enklaste lösningen vara att dra upp nodejs och tvinga den att generera ett arkiv med konfigurationer med hjälp av direktlänkar.
Egentligen fanns det inte många alternativ. Mer exakt kom bara en att tänka på. Vi måste ställa in konfigurationerna och få en länk som vi kan kopiera till serverkonsolen för att få ett zip-arkiv.
Flera textfiler i det resulterande zip-arkivet vägde ganska mycket, bokstavligen några kilobyte. Den uppenbara lösningen var att hämta base64-strängen från det genererade zip-arkivet och slänga den i bufferten, medan på servern med kommandot i konsolen

echo 'base64string' | base64 --decode > config.zip

vi skulle kunna skapa samma zip-fil.

nginxconfig.io skrevs i AngularJS, jag kan inte ens föreställa mig vilken kilometer kod som skulle ha krävts om författaren inte hade valt ett reaktivt js-ramverk. Men jag kan perfekt föreställa mig hur mycket enklare och vackrare allt detta skulle kunna implementeras i VueJS, även om detta är ett helt annat ämne.
I projektresurserna ser vi en metod för att skapa ett zip-arkiv:

$scope.downloadZip = function() {
	var zip = new JSZip();

	var sourceCodes = $window.document.querySelectorAll('main .file .code.source');

	for (var i = 0; i < sourceCodes.length; i++) {
		var sourceCode = sourceCodes[i];

		var name	= sourceCode.dataset.filename;
		var content	= sourceCode.children[0].children[0].innerText;

		if (!$scope.isSymlink() && name.match(/^sites-available//)) {
			name = name.replace(/^sites-available//, 'sites-enabled/');
		}

		zip.file(name, content);

		if (name.match(/^sites-available//)) {
			zip.file(name.replace(/^sites-available//, 'sites-enabled/'), '../' + name, {
				unixPermissions: parseInt('120755', 8),
			});
		}
	}

	zip.generateAsync({
		type: 'blob',
		platform: 'UNIX',
	}).then(function(content) {
		saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');
	});

	gtag('event', $scope.getDomains().join(','), {
		event_category: 'download_zip',
	});
};

allt är ganska enkelt, med hjälp av biblioteket jszip En zip skapas där konfigurationsfilerna placeras. Efter att ha skapat zip-arkivet matar js det till webbläsaren med hjälp av biblioteket FileSaver.js:

saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');

där innehållet är det resulterande blobobjektet i zip-arkivet.

Ok, allt jag behövde göra var att lägga till en annan knapp bredvid den och när jag klickade på den skulle jag inte spara det resulterande zip-arkivet i webbläsaren, utan hämta base64-koden från den. Efter att ha pillat runt lite fick jag 2 metoder, istället för bara en downloadZip:

$scope.downloadZip = function() {
	generateZip(function (content) {
		saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');
	});

	gtag('event', $scope.getDomains().join(','), {
		event_category: 'download_zip',
	});
};
$scope.downloadBase64 = function() {
	generateZip(function (content) {
		var reader = new FileReader();
		reader.readAsDataURL(content);
		reader.onloadend = function() {
			var base64 = reader.result.replace(/^data:.+;base64,/, '');
			// в переменной base64 как раз нужный мне zip архив в виде base64 строки
		}
	});

	gtag('event', $scope.getDomains().join(','), {
		event_category: 'download_base64',
	});
};

Som du kanske har märkt flyttade jag genereringen av själva zip-arkivet till den privata genereraZip-metoden, och så vidare. Detta är AngularJS, och författaren själv håller sig till callbacks och implementerade det inte genom löften. downloadZip gjorde fortfarande saveAs som en utdata, medan downloadBase64 gjorde något lite annorlunda. Vi skapar ett FileReader-objekt som kom till oss i html5 och som redan är ganska tillgängligt för användning. Som på en gång kan göra en base64-sträng från en blob, eller snarare, den gör en DataURL-sträng, men detta är inte så viktigt för oss, eftersom DataURL innehåller precis vad vi behöver. Bingo, en liten hake väntade mig när jag försökte lägga allt detta i bufferten. Författaren använde biblioteket i projektet clipboardjs, som låter dig arbeta med klippbordet utan flash-objekt, baserat på den markerade texten. Till en början bestämde jag mig för att lägga min base64 i ett element med display:none;, men i det här fallet kunde jag inte lägga den på urklippet eftersom ingen separation sker. Därför, istället för display:none; jag gjorde

position: absolute;
z-index: -1;
opacity: 0;

vilket gjorde att jag både kunde dölja elementet och faktiskt lämna det på sidan. Voila, uppgiften var klar, när jag klickade på min knapp placerades en rad så här i bufferten:

echo 'base64string' | base64 --decode > config.zip

som jag helt enkelt klistrade in i konsolen på servern och omedelbart fick ett zip-arkiv med alla konfigurationer.
Och, naturligtvis, skickade jag en pull-förfrågan till författaren, eftersom... projektet är aktivt och livligt, jag skulle vilja se uppdateringar från författaren och ha en egen knapp) För den som är intresserad, här är den min gaffel projektet och sig själv dra förfrågan, där du kan se vad jag korrigerade/lägg till.
Trevlig utveckling alla)

Generering av konfigurationer för nginx, historik för en pull-begäran

Källa: will.com

Lägg en kommentar