Xterm.js: Suporte para ZModem?

Criado em 19 set. 2016  ·  41Comentários  ·  Fonte: xtermjs/xterm.js

suporta ZModem para que possamos receber / enviar arquivos usando lrzsz? Isso parece interessante?

Comentários muito úteis

Se eu puder adicionar meus dois centavos em relação à forma disso para torná-lo um plugin xterm: eu proporia não adicionar uma IU, mas despachar as coisas por meio de um evento, semelhante a fluxos de nó. Algo como

term.on('transfer', (transfer) => {

  // accept or reject the transfer
  transfer.accept();

  // listen for progress
  transfer.on('progress', ...);

  // data chunks arrive
  transfer.on('data', ...);

  // transfer has finished
  transfer.once('end', ...);

  // cancel transfer
  transfer.abort();

});

Dessa forma, um consumidor pode construir sua própria IU sobre o plug-in.

Todos 41 comentários

Você poderia entrar em mais alguns detalhes sobre como isso funcionaria no xterm.js?

Eu uso xterm.js para me conectar a um bash (um bash completo) e permitir que o usuário interaja com o bash. Gostaria que o usuário de suporte carregue / baixe o arquivo através do terminal da web usando rz / sz.

Se eu me conectar ao shell de uma máquina com SecureCRT / Xshell, posso fazer upload / download de arquivos com o comando rz / sz . Gostaria de usar zterm.js para conectar ao shell de uma máquina e fazer upload / download de arquivos com o comando rz / sz

Zmodem é um recurso de protocolo da abstração de linha serial subjacente do sistema PTY. Isso já pode ser usado com ferramentas como zssh em xterm.js. O próprio xterm.js está apenas encaminhando o IO mestre do PTY para o navegador. Na realidade, você está operando no sistema em que a parte do servidor xterm.js está hospedada.

Isso é bem diferente de um emulador de terminal operando na mesma máquina como o SecureCRT faz.

Portanto, a questão é - de qual máquina para qual máquina você deseja mover os arquivos através do terminal? (Lembre-se de que sua máquina local não tem canal de terminal para a parte do servidor de xterm.js).

|       local machine               |
|   +----------------------------+  |
|   |       browser              |  |
|   |   +-------------------+    |  |               +---------------------------+          +------------------------+
|   |   |                   |    |  |               |   proxy                   |          |                        |
|   |   |   web terminal    >----------------------->   server part of xterm.js >----------| romote machine terminal|
|   |   |                   |    |  |               +---------------------------+          +------------------------+
|   |   |                   |    |  |
|   |   +-------------------+    |  |
|   +----------------------------+  |
+-----------------------------------+

Eu gostaria de mover arquivos da máquina local para a máquina remota. A máquina remota não pode ser acessada pela máquina local diretamente, pois não possui ip externo.

Lembre-se de que sua máquina local não tem canal de terminal para a parte do servidor de xterm.js

Existe alguma solução alternativa para isso?

Bem, você pode usar zssh (com suporte a zmodem), sftp ou scp do proxy.

A menos que alguém o implemente, não há como fazer upload / download de arquivos diretamente do terminal da web em seu navegador para a máquina remota. Um dos protocolos de modem poderia ser usado dessa forma (há uma implementação XModem JS), mas como o navegador tem acesso muito limitado ao sistema de arquivos, questiono a utilidade. A parte difícil seria fornecer uma interação de download com o navegador para arquivos grandes (uma vez que os dados chegam diretamente no navegador por meio do websocket, JS teria que manter todos os dados até que possam ser salvos).

Outra abordagem seria aprimorar a parte do servidor com a funcionalidade rz / sz e mapear isso de forma transparente para o navegador. Isso contornaria as limitações FS do navegador, mas precisaria conectar outro analisador ao fluxo do terminal para capturar a inicialização 'rz \ r' dos protocolos do modem.

Estou trabalhando em uma implementação de ZMODEM em JavaScript e transferindo arquivos em ambas as direções via xterm.js.

O navegador realmente precisa armazenar todo o arquivo em buffer ao recebê-lo. :( Essa é realmente a única desvantagem, e não é ruim, a menos que você esteja enviando arquivos muito grandes. Uploads podem ser feitos via FileReader e downloads acontecem por meio do atributo “download” dos elementos <a> .

Ainda estou testando e documentando, mas a integração do ZMODEM é um recurso que interessaria ao xterm.js?

@FGasper Nice :) Parece promissor, se você implementá-lo com a API de fluxo do nó, ele também pode ser útil para arquivos grandes como uma extensão do lado do servidor, que faz o proxy desses arquivos para o endpoint do navegador através do link de download.

A biblioteca em si é independente de plataforma, portanto, deve funcionar em qualquer lugar. (Bata na madeira.)

@FGasper parece legal 😄!

Podemos definitivamente considerar um addon zmodem, se funcionar no navegador.

Quais são geralmente os casos de uso para usar zmodem?

Eu o uso para fazer transferências de arquivos em uma sessão de terminal de / para minha estação de trabalho. Ele permite que você não precise scp / sftp ou o que não seja.

Semelhante a este para iTerm2:
https://github.com/mmastrac/iterm2-zmodem

@parisk Os rz / sz para fazer isso.

Bem, para xterm.js, é um complemento perfeito, pois aumentará a utilidade do xterm.js para administradores de servidores em ambientes restritos. : +1:

NB: XMODEM e YMODEM têm a desvantagem de não “avisar” o outro lado que há uma transferência de arquivo pronta. (É lamentável porque eles são muito mais simples!)

ZMODEM envia o que é essencialmente uma “string mágica” que pode ser observada; em seguida, você pergunta ao usuário, “ZMODEM detectado; continuar com a transferência de arquivos? ” Nesse ponto, a implementação fornece meios para fornecer arquivos para transferência ou para aceitar / pular arquivos conforme o remetente os oferece.

Para xterm.js, seria legal apenas arrastar e soltar arquivos no terminal - digamos que um arquivo seja salvo no caminho do shell do terminal atual. Mas isso é muito complicado de realizar, a menos que xterm.js possa controlar o próprio shell remoto ou pelo menos obter o diretório de trabalho atual em qualquer ponto. O mesmo vale para as versões anteriores - se uma listagem ls pudesse ser identificada como referindo-se a arquivos remotos, arrastar e soltar do terminal seria ótimo. Bem, apenas sonhando: piscadela:

Não vejo por que arrastar / soltar rz não seria possível depois que a sessão do Zmodem fosse iniciada. Pode ser implementado de várias maneiras, mas talvez:

1) Digite rz em seu console.
2) Arraste / solte os arquivos.
3) Inicie a transferência.

Pergunta: Até que ponto o xterm.js ainda é compatível com o IE?

Não há mais suporte ao IE na v3 devido a https://github.com/sourcelair/xterm.js/pull/938 , os desenvolvedores devem sair dele de qualquer maneira.

Eu gostaria de mostrar a vocês uma demonstração.

Tenho testado em meu próprio servidor de terminal, mas gostaria de usar o que vocês têm como padrão.

image
^^ Estou faltando alguma coisa aqui? npm install erros para mim…

felipe@Macintosh-4 18:00:56 ~/code/p5-Net-WebSocket/demo
> sudo npm install
npm ERR! install Couldn't read dependencies
npm ERR! Darwin 16.7.0
npm ERR! argv "/opt/local/bin/node" "/opt/local/bin/npm" "install"
npm ERR! node v8.3.0
npm ERR! npm  v2.15.12
npm ERR! path /Users/felipe/package.json
npm ERR! code ENOPACKAGEJSON
npm ERR! errno -2
npm ERR! syscall open

npm ERR! package.json ENOENT: no such file or directory, open '/Users/felipe/package.json'
npm ERR! package.json This is most likely not a problem with npm itself.
npm ERR! package.json npm can't find a package.json file in your current directory.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/felipe/code/p5-Net-WebSocket/demo/npm-debug.log

Talvez você tenha esquecido git clone ... ? E por que com sudo ?

@FGasper

npm ERR! package.json ENOENT: no such file or directory, open '/Users/felipe/package.json'

Você está executando npm install em seu diretório inicial, não no diretório repo.

Existe uma maneira de fazer com que o node-pty produza binários em vez de strings? ZMODEM é um protocolo binário, mas a demonstração parece pensar que tudo é UTF-8. Em particular, algo parece estar convertendo 0x8a em UTF-8 \ ufffd

Isso pode ser um pouco mais envolvente - para uma solução rápida, você pode tentar desabilitar os codificadores de node-pty ou definir o tipo de string para 'binário', mas isso pode ter impactos indesejados na transferência de websocket para xterm.js. Pelo que eu posso dizer, toda a cadeia node-pty <---> websocket <---> xterm.js depende de bytes UTF-8 que são decodificados para strings JS em tempo real. Pode ser necessário um patch maior para obter o fluxo de dados binários.

Onde está essa configuração de tipo de string binary ? (Não vejo tal em node-pty?)

Pelo que posso dizer, os dados já estão corrompidos no momento em que atingem app.js , então a mudança no comportamento teria que ser em node-pty.

ZMODEM apresenta uma codificação que escapa de todos os caracteres de bit alto para 7 bits, mas aparentemente nunca foi implementada de fato ... Forsberg provavelmente percebeu que nunca seria necessário, pois todas as linhas se tornaram seguras de 8 bits, heh. :)

Você pode tentar com {encoding: 'binary'} nas opções do ctor ou .setEncoding('binary') na hora.

Parece que o node-pty mais recente permite definir ou não definir o modo UTF8 ...

  if (info[8]->ToBoolean()->Value()) {
#if defined(IUTF8)
    term->c_iflag |= IUTF8;
#endif
}

https://github.com/Tyriar/node-pty/blob/master/src/unix/pty.cc

Hm ... o node-pty que o xterm.js puxa (0.4.1) é muito antigo ... talvez a versão mais recente inclua esse sinalizador.

Chamar .setEncoding('binary') não funciona… e nem passar encoding:"binary" para pty.spawn ().

IUTF8 de termios faz uma coisa diferente - permite o manuseio correto de caracteres UTF8 de vários bytes no dispositivo pty (para largura de linha e apagamento).
Hmm, talvez a maneira mais difícil - tente remover o codificador:

delete ptyObj._socket._readableState.decoder;
delete ptyObj._socket._readableState.encoding;

Isso deve fornecer a você objetos de buffer em vez de strings (provavelmente para quebrar em xterm.js).

OK, consegui atualizando para node-pty 0.6.4 e definindo a codificação para null . (Não precisava do material _readableState .) Ele ainda envia a primeira linha da sessão do shell como texto, mas tudo que vem depois é binário, muito legal.

Ele ainda envia a primeira linha da sessão de shell como texto ...

Mesmo se você aplicá-lo ao construtor como {encoding: null} ?

Sim, mesmo com {encoding: null} a primeira linha é enviada como um quadro de texto.

Eu coloquei isso em um estado que considero razoável para experimentar.

1) Configure https://github.com/FGasper/xterm.js.git como um controle remoto.
2) Verifique o branch zmodem desse repo.
3) git submodule init; git submodule update
4) npm install (veja abaixo).
5) npm start e carregue localhost:3000 no navegador. (Chrome é o que eu testei.)
6) ssh para uma máquina que possui lrzsz instalado.
7) Digite rz e envie um ou mais arquivos de sua estação de trabalho para o remoto.
8) sz <filename1> <filename2> … enviará arquivos em lote para sua estação de trabalho.

(A interface do usuário é mínima por design; presumivelmente, uma implantação "real" a aprimoraria mais.)

Com relação à etapa 4: Quando testei agora mesmo em minha estação de trabalho, tive que corrigir um problema de permissão com o pacote node-gyp .

Legal, funciona perfeitamente (testado com arquivos de texto no Firefox).

Apenas algumas observações:

  • É possível acionar a sequência de inicialização por acidente (por exemplo, saída de dados aleatórios)? Nesse caso, o terminal IMHO precisaria de uma configuração "inserir transferência de arquivo" para tornar isso explícito.
  • O "Iniciar sessão ZMODEM" deve ser interrompível, selecionar "Não" não aborta rz na outra extremidade do atm.
  • É possível desenhar alguma barra / indicador de progresso no widget do terminal enquanto a transferência está em andamento? Ou alguma outra coisa mais sofisticada, atm rz/sz imprime alguns números de status estranhos no terminal.

@jerch

1) Sim, é possível acionar a sequência de inicialização acidentalmente. É para isso que serve o prompt “Iniciar sessão ZMODEM”: o usuário ainda pode desistir, se necessário.

2) Deve ser corrigido agora.

3) O aplicativo recebe eventos progress sincronizados com a API FileReader do navegador. O Chrome parece fornecer conteúdo com progress ; entretanto, o Firefox não fornece realmente o conteúdo do arquivo nesses eventos. Se você enviar a si mesmo um arquivo adequadamente grande no Chrome, verá algo como:
image

4) Os caracteres estranhos no início de uma sessão são as partes imprimíveis da seqüência de recepção de ZMODEM: ** + ASCII CAN + B01 + 10 caracteres hexadecimais + CR + 0x8a + XON. Eu concordo que é feio eles irem para a tela; no entanto, é bastante padrão nos terminais habilitados para ZMODEM que usei. Suponho que poderia enviar caracteres BS suficientes para o terminal para excluir esses caracteres.

Também é necessário adicionar um controle para cancelar uma transferência em andamento. Ainda estou procurando a melhor maneira de lidar com isso.

Também é necessário adicionar um controle para cancelar uma transferência em andamento. Ainda estou procurando a melhor maneira de lidar com isso.

Talvez isso das especificações ajude?

A ZFIN, ZABORT, or TIMEOUT terminates the session; a ZSKIP terminates the processing of
this file.

Potencialmente. A especificação nem sempre é a coisa mais útil; por exemplo, ele menciona uma sequência Attn que é enviada após um ZSINIT. A especificação parece sugerir que é assim que um remetente pausa um envio de dados, mas aparentemente nada usa Attn. Da mesma forma com a opção ESC8: não é realmente implementado em lrzsz e, uma vez que essa é a implementação de referência de fato, ESC8 é inutilizável - o que é uma pena porque resolveria bem esse problema com o sinalizador IEXTEN termios.

Estou com um pouco de falta de tempo em outros projetos agora, mas espero voltar a isso na próxima semana.

Se eu puder adicionar meus dois centavos em relação à forma disso para torná-lo um plugin xterm: eu proporia não adicionar uma IU, mas despachar as coisas por meio de um evento, semelhante a fluxos de nó. Algo como

term.on('transfer', (transfer) => {

  // accept or reject the transfer
  transfer.accept();

  // listen for progress
  transfer.on('progress', ...);

  // data chunks arrive
  transfer.on('data', ...);

  // transfer has finished
  transfer.once('end', ...);

  // cancel transfer
  transfer.abort();

});

Dessa forma, um consumidor pode construir sua própria IU sobre o plug-in.

@mofux É assim que eu gostaria que isso funcionasse também. Os componentes da IU que coloquei na demonstração destinam-se apenas a demonstrar os controles.

@FGasper Bom trabalho 👍

Vou adicionar suporte ZModem para ttyd quando sua API estiver pronta para uso (https://github.com/tsl0922/ttyd/issues/37), obrigado por seu trabalho.

https://www.npmjs.com/package/zmodem.js

Fiz uma versão ALPHA do zmodem.js. A partir daqui, examinarei a interface do plug-in para xterm.js, mas quem quiser ver o zmodem.js, sinta-se à vontade para fazê-lo e me dizer como ele funciona para você.

O addon ZMODEM agora está mesclado, FYI.

sistema win7

$ npm run start-zmodem

> [email protected] start-zmodem E:\test\xterm\xterm.js
> node demo/zmodem/app

App listening to http://127.0.0.1:3100

por que não consigo abrir o File Explorer?
default

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

tandatle picture tandatle  ·  3Comentários

Mlocik97-issues picture Mlocik97-issues  ·  3Comentários

goxr3plus picture goxr3plus  ·  3Comentários

Tyriar picture Tyriar  ·  4Comentários

jestapinski picture jestapinski  ·  3Comentários