Δημιουργία ρυθμίσεων για nginx, ιστορικό ενός αιτήματος έλξης

Χαιρετισμούς, σύντροφοι. Όμορφο στους διακομιστές μάχης μου nginx τρέχει από το 2006 και με τα χρόνια της διαχείρισής του έχω συγκεντρώσει πολλές ρυθμίσεις και πρότυπα. Επαίνεσα πολύ το nginx και κατά κάποιο τρόπο αποδείχτηκε ότι ξεκίνησα και ένα nginx hub στο hub, επίσης, show off m/
Φίλοι μου ζήτησαν να δημιουργήσω ένα αγρόκτημα ανάπτυξης για αυτούς και αντί να τους σύρω τα συγκεκριμένα πρότυπά μου, θυμήθηκα ένα ενδιαφέρον έργο nginxconfig.io, το οποίο διασκορπίζει παραμέτρους στα ράφια και προετοιμάζει τα πάντα για κρυπτογράφηση, κ.λπ. Σκέφτηκα, γιατί όχι; Ωστόσο, με εξόργισε το γεγονός ότι το nginxconfig μου προσφέρει να κατεβάσω το αρχείο zip στο πρόγραμμα περιήγησης, χωρίς να μου επιτρέπει να το ανεβάσω απευθείας στον διακομιστή χρησιμοποιώντας το wget/fetch/curl. Τι βλακείες, γιατί το χρειάζομαι στο πρόγραμμα περιήγησης, το χρειάζομαι στον διακομιστή από την κονσόλα. Θυμωμένος, πήγα στο github για να δω τα κότσια του έργου, το οποίο οδήγησε στο πιρούνι του και, ως εκ τούτου, σε ένα αίτημα έλξης. Για το οποίο δεν θα έγραφα αν δεν ήταν ενδιαφέρον 😉

Δημιουργία ρυθμίσεων για nginx, ιστορικό ενός αιτήματος έλξης

Φυσικά, προτού ψάξω τις πηγές, κοίταξα πού τραβάει ο Chrome το αρχείο zip που δημιουργήθηκε με τις ρυθμίσεις παραμέτρων και εκεί με περίμενε μια διεύθυνση που ξεκινούσε με "blob:", ωχ. Έχει γίνει ήδη σαφές ότι η υπηρεσία δεν δημιουργεί τίποτα στην πορεία, στην πραγματικότητα, όλα γίνονται από το js. Πράγματι, το αρχείο zip δημιουργείται από τον πελάτη, το πρόγραμμα περιήγησης και το ίδιο το javascript. Εκείνοι. η ομορφιά είναι ότι το έργο nginxconfig.io μπορεί απλά να αποθηκευτεί ως σελίδα html, να μεταφορτωθεί σε ορισμένους narod.ru και θα λειτουργήσει) Αυτή είναι μια πολύ αστεία και ενδιαφέρουσα λύση, ωστόσο, είναι τρομερά άβολη για τη ρύθμιση διακομιστών, στην πραγματικότητα, ακριβώς για αυτό που δημιουργήθηκε αυτό το έργο. Κάντε λήψη του αρχείου που δημιουργήθηκε με ένα πρόγραμμα περιήγησης και, στη συνέχεια, μεταφέρετέ το στον διακομιστή χρησιμοποιώντας nc... το 2019; Έθεσα στον εαυτό μου καθήκον να βρω έναν τρόπο να κατεβάσω τη διαμόρφωση που προκύπτει απευθείας στον διακομιστή.
Αφού διέλυσα το έργο, άρχισα να σκέφτομαι ποιες ήταν οι επιλογές μου. Το έργο ήταν περίπλοκο από το γεγονός ότι δεν ήθελα να παρεκκλίνω από την προϋπόθεση ότι το έργο θα έπρεπε να παραμείνει ένα καθαρό front-end, χωρίς κανένα back-end. Φυσικά, η απλούστερη λύση θα ήταν να ανακτήσετε το nodej και να το αναγκάσετε να δημιουργήσει ένα αρχείο με ρυθμίσεις παραμέτρων χρησιμοποιώντας άμεσους συνδέσμους.
Στην πραγματικότητα, δεν υπήρχαν πολλές επιλογές. Πιο συγκεκριμένα, μόνο ένα μου ήρθε στο μυαλό. Πρέπει να ρυθμίσουμε τις ρυθμίσεις παραμέτρων και να λάβουμε έναν σύνδεσμο που μπορούμε να αντιγράψουμε στην κονσόλα διακομιστή για να αποκτήσουμε ένα αρχείο zip.
Πολλά αρχεία κειμένου στο αρχείο zip που προέκυψε ζύγιζαν αρκετά, κυριολεκτικά μερικά kilobyte. Η προφανής λύση ήταν να λάβετε τη συμβολοσειρά base64 από το αρχείο zip που δημιουργήθηκε και να την πετάξετε στο buffer, ενώ βρίσκεστε στον διακομιστή με την εντολή στην κονσόλα

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

θα μπορούσαμε να δημιουργήσουμε αυτό το ίδιο αρχείο zip.

nginxconfig.io γράφτηκε στο AngularJS, δεν μπορώ καν να φανταστώ πόσα χιλιόμετρα κώδικα θα χρειάζονταν αν ο συγγραφέας δεν είχε επιλέξει ένα reactive js πλαίσιο. Μπορώ όμως να φανταστώ τέλεια πόσο απλούστερα και πιο όμορφα όλα αυτά θα μπορούσαν να εφαρμοστούν στο VueJS, αν και αυτό είναι ένα εντελώς διαφορετικό θέμα.
Στους πόρους του έργου βλέπουμε μια μέθοδο για τη δημιουργία ενός αρχείου zip:

$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',
	});
};

όλα είναι πολύ απλά, χρησιμοποιώντας τη βιβλιοθήκη jszip Δημιουργείται ένα zip όπου τοποθετούνται τα αρχεία διαμόρφωσης. Αφού δημιουργήσετε το αρχείο zip, το js το τροφοδοτεί στο πρόγραμμα περιήγησης χρησιμοποιώντας τη βιβλιοθήκη FileSaver.js:

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

όπου το περιεχόμενο είναι το αντικείμενο blob που προκύπτει του αρχείου zip.

Εντάξει, το μόνο που έπρεπε να κάνω ήταν να προσθέσω ένα άλλο κουμπί δίπλα του και όταν έκανα κλικ σε αυτό, δεν θα αποθηκεύσω το αρχείο zip που προέκυψε στο πρόγραμμα περιήγησης, αλλά θα έπαιρνα τον κωδικό base64 από αυτό. Αφού έψαξα λίγο, πήρα 2 μεθόδους, αντί για μία μόνο λήψη Zip:

$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',
	});
};

Όπως ίσως έχετε παρατηρήσει, μετακίνησα τη δημιουργία του ίδιου του αρχείου zip στη μέθοδο private generateZip και ούτω καθεξής. Αυτό είναι το AngularJS και ο ίδιος ο συγγραφέας εμμένει στις επανακλήσεις και δεν το υλοποίησε μέσω υποσχέσεων. Το downloadZip εξακολουθούσε να έχει saveAs ως έξοδο, ενώ το downloadBase64 έκανε κάτι ελαφρώς διαφορετικό. Δημιουργούμε ένα αντικείμενο FileReader που μας ήρθε σε html5 και είναι ήδη αρκετά διαθέσιμος για χρήση. Το οποίο, σε μια στιγμή, μπορεί να δημιουργήσει μια συμβολοσειρά base64 από μια blob, ή μάλλον, δημιουργεί μια συμβολοσειρά DataURL, αλλά αυτό δεν είναι τόσο σημαντικό για εμάς, επειδή Το DataURL περιέχει ακριβώς αυτό που χρειαζόμαστε. Μπίνγκο, με περίμενε μια μικρή εμπλοκή όταν προσπάθησα να τα βάλω όλα αυτά στο buffer. Ο συγγραφέας χρησιμοποίησε τη βιβλιοθήκη στο έργο clipboardjs, που σας επιτρέπει να εργάζεστε με το πρόχειρο χωρίς αντικείμενα flash, με βάση το επιλεγμένο κείμενο. Αρχικά, αποφάσισα να βάλω το base64 σε ένα στοιχείο με display:none;, αλλά σε αυτήν την περίπτωση δεν μπορούσα να το βάλω στο πρόχειρο γιατί δεν γίνεται διαχωρισμός. Επομένως, αντί για display:none; το έκανα

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

που μου επέτρεψε να κρύψω το στοιχείο από την προβολή και να το αφήσω στη σελίδα. Voila, η εργασία ολοκληρώθηκε, όταν έκανα κλικ στο κουμπί μου, μια γραμμή όπως αυτή τοποθετήθηκε στο buffer:

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

το οποίο απλώς επικολλούσα στην κονσόλα του διακομιστή και έλαβα αμέσως ένα αρχείο zip με όλες τις ρυθμίσεις παραμέτρων.
Και, φυσικά, έστειλα αίτημα έλξης στον συγγραφέα, γιατί... το έργο είναι ενεργό και ζωντανό, θα ήθελα να δω ενημερώσεις από τον συγγραφέα και να έχω το δικό μου κουμπί) Για όσους ενδιαφέρονται, εδώ είναι το πιρούνι μου έργο και τον εαυτό μου pull request, όπου μπορείτε να δείτε τι διόρθωσα/πρόσθεσα.
Καλή εξέλιξη σε όλους)

Δημιουργία ρυθμίσεων για nginx, ιστορικό ενός αιτήματος έλξης

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο