Saudações, camaradas. Nos meus servidores de batalha, o
nginx bonito gira desde 2006 e, ao longo dos anos de administração, acumulei muitas configurações e modelos. Elogiei muito o nginx e, de alguma maneira, até o hub do nginx em Habr também me iniciou, mostre \ m /
Amigos me pediram para criar um farm de desenvolvimento para eles e, em vez de arrastá-los com meus modelos específicos, lembrei-me de um projeto interessante
nginxconfig.io , que dispersa as configurações e prepara tudo para criptografar, etc. Eu pensei, por que não? No entanto, fiquei furioso pelo fato de o nginxconfig me oferecer o download do arquivo zip para o navegador, não me permitindo mesclá-lo diretamente no servidor usando wget / fetch / curl. Que tipo de bobagem, por que eu preciso disso no navegador, preciso no servidor do console. Com raiva, subi no github para ver as entranhas do projeto, que levaram ao garfo e, como resultado, puxaram a solicitação. Sobre o qual eu não escreveria se não fosse interessante;)

É claro que, antes de escolher a fonte, olhei de onde o chrome puxa o arquivo zip gerado com as configurações e estava esperando o endereço começando com "blob:", oppa. Já ficou claro que, no processo, o serviço não gera nada, de fato, o js faz tudo isso. De fato, o arquivo zip é gerado pelo próprio cliente, navegador, javascript. I.e. o charme é que o projeto
nginxconfig.io pode ser simplesmente salvo como uma página html, carregado em algum
narod.ru e funcionará) do que este projeto foi criado. Baixe o arquivo gerado pelo navegador e transfira-o para o servidor usando nc ... em 2019? Eu me propus a tarefa de encontrar uma maneira de baixar a configuração resultante diretamente no servidor.
Tendo bifurcado o projeto, comecei a pensar em quais opções tenho. A tarefa foi complicada pelo fato de eu não querer abandonar a condição de que o projeto permanecesse um front-end limpo, sem nenhum back-end. Obviamente, a solução mais simples seria acessar o nodejs e gerar um arquivo com configurações via links diretos.
De fato, não havia muitas opções. Mais precisamente, apenas um veio à mente. Precisamos configurar as configurações e obter um link que possamos copiar para o console do servidor para obter um arquivo zip.
Vários arquivos de texto no arquivo zip resultante pesavam bastante, literalmente alguns kilobytes. A solução óbvia foi obter a sequência base64 do arquivo zip gerado e jogá-la no buffer, enquanto estava no servidor com o comando no console
echo 'base64string' | base64 --decode > config.zip
nós poderíamos criar esse mesmo arquivo zip.
O nginxconfig.io foi escrito no AngularJS, nem consigo imaginar quais quilômetros de código seriam necessários se o autor não escolhesse uma estrutura js reativa. Mas imagino perfeitamente o quanto mais fácil e bonito seria possível implementar tudo isso no VueJS, embora esse já seja um tópico completamente diferente.
Nos recursos do projeto, vemos um método para gerar um arquivo 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', }); };
tudo é bem simples, usando a biblioteca
jszip , um zip é criado onde os arquivos de configuração são colocados. Após criar o arquivo zip, o js o alimenta no navegador usando a biblioteca
FileSaver.js :
saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');
onde o conteúdo é o objeto de arquivo zip do blob resultante.
Ok, tudo o que eu precisava fazer era adicionar outro botão ao lado e, quando clicar nele, não salve o arquivo zip resultante no navegador, mas obtenha o código base64. Depois de um pouco de xamanismo, obtive 2 métodos, em vez de um 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,/, '');
Como você pode ver, coloquei a geração do arquivo zip no método generateZip privado, bem, porque este é AngularJS, e o próprio autor adere a retornos de chamada, não o implementou por meio de promessas. O downloadZip ainda salvouAs na saída, enquanto o downloadBase64 foi um pouco diferente. Criamos um objeto FileReader que chegou até nós em html5 e já está
disponível para uso. Que, no devido tempo, sabe como criar uma string base64 a partir de blob, mais precisamente, cria uma string DataURL, mas isso não é tão importante para nós, porque DataURL contém exatamente o que precisamos. Bingo, um pequeno problema estava me esperando quando tentei colocar tudo isso em um buffer. O autor usou a biblioteca
clipboardjs no projeto, que permite trabalhar com a área de transferência sem objetos flash, com base no texto selecionado. Inicialmente, eu decidi colocar minha base64 em um elemento com display: none;, mas nesse caso eu não poderia colocá-lo na área de transferência, porque nenhuma seleção ocorre. Portanto, em vez de exibir: nenhum; eu fiz
position: absolute; z-index: -1; opacity: 0;
o que me permitiu esconder o elemento dos meus olhos e deixá-lo na página. Voila, a tarefa está concluída, quando eu cliquei no meu botão, uma linha do formulário foi colocada no buffer:
echo 'base64string' | base64 --decode > config.zip
que simplesmente inseri no console do servidor e recebi imediatamente um arquivo zip com todas as configurações.
Bem, é claro, joguei a solicitação pull ao autor, porque o projeto é ativo e animado, quero ver atualizações do autor e ter meu próprio botão) Quem se importa, aqui está o
meu fork do projeto e a
solicitação pull , onde você pode ver o que eu consertei / atualizei.
Desenvolvimento Peppy :-)
