FGasper / zmodemjs

zmodem.js - ZMODEM in JavaScript
Apache License 2.0
129 stars 25 forks source link

Uncaught TypeError: Cannot read property 'ZRPOS' of null #11

Closed zhinian99 closed 4 years ago

zhinian99 commented 4 years ago

_Uncaught TypeError: Cannot read property 'ZRPOS' of null at r.Session.Send._consume_header (VM72 zmodem.js:1) at r.Session.Send._parse_and_consume_header (VM72 zmodem.js:1) at r.Session.Send._consumefirst (VM72 zmodem.js:1) at r.Session.Send.consume (VM72 zmodem.js:1) at t.Sentry.consume (VM72 zmodem.js:1) at WebSocket.handleWSMessage (VM73 zmodem.js:30)

When I use 'rz' to upload a file,I got this. So what`s the probrom.

FGasper commented 4 years ago

You probably have a bug in how you’re calling zmodemjs.

If you can submit a PR with a test that demonstrates that there’s a bug in this library I’ll look though.

Unfortunately, ZMODEM is just a hard protocol to implement.

leffss commented 4 years ago

You probably have a bug in how you’re calling zmodemjs.

If you can submit a PR with a test that demonstrates that there’s a bug in this library I’ll look though.

Unfortunately, ZMODEM is just a hard protocol to implement.

@FGasper thanks for your great project. In my project django-webssh and gowebssh, I use zmodemjs to implement upload and download functions, but this error often occurs, just like @zhinian99 . I also found that if you use rz -O to upload file, this problem will be improved.

FGasper commented 4 years ago

@leffss: Best thing would be a PR with a test that reproduces the problem.

It looks like it’s bugging out here:

var handler = this._next_header_handler[ new_header.NAME ];

Assuming the API is being used as intended, that means there’s a ZRPOS being sent that zmodem.js doesn’t know how to handle.

I suggest adding some debugging statements and seeing if you can further diagnose the problem.

FGasper commented 4 years ago

I’ve made a debug branch:

https://github.com/FGasper/zmodemjs/tree/extra_zrpos

It makes the error report a bit “kinder” and turns on debugging. Let me know if that clarifies anything.

FGasper commented 4 years ago

@leffss @zhinian99 ^^

leffss commented 4 years ago

I’ve made a debug branch:

https://github.com/FGasper/zmodemjs/tree/extra_zrpos

It makes the error report a bit “kinder” and turns on debugging. Let me know if that clarifies anything.

I used the debug branch https://github.com/FGasper/zmodemjs/tree/extra_zrpos .

1

As you said: ZMODEM is just a hard protocol to implement, I still don't understand what happened...

And I also found if use rz -O (disable timeout code, wait forever for data) to upload file, it will work well.

2

FGasper commented 4 years ago

@leffss Thank you.

Are you sending just a single file, or multiple files? In the first screenshot it looks like two files are being sent.

I’ve pushed up a few more debugging statements … do you mind retrying?

If you can send me reproduction steps I’ll give it a go on this end.

leffss commented 4 years ago

@leffss Thank you.

Are you sending just a single file, or multiple files? In the first screenshot it looks like two files are being sent.

I’ve pushed up a few more debugging statements … do you mind retrying?

If you can send me reproduction steps I’ll give it a go on this end.

I test it again.

1

2

3

FGasper commented 4 years ago

@leffss It looks like these latest screenshots don’t include the additional debugging data … do you mind trying with that?

Thank you for clarifying that the issue pertains to multiple-file transfer sessions.

leffss commented 4 years ago

@leffss It looks like these latest screenshots don’t include the additional debugging data … do you mind trying with that?

Thank you for clarifying that the issue pertains to multiple-file transfer sessions.

Ok, I will test it with the lastest debug branch.

leffss commented 4 years ago

@leffss It looks like these latest screenshots don’t include the additional debugging data … do you mind trying with that?

Thank you for clarifying that the issue pertains to multiple-file transfer sessions.

Latest test results with the lastest debug branch.

1

2

3

4

FGasper commented 4 years ago

@leffss: So, assuming the -O flag is unused, the issue appears sometimes when transferring a single file, but always when transferring multiples?

FGasper commented 4 years ago

@leffss Each zmodem packet consists of a type and 4 octets. I’m pushing up another change to the debug branch to expose those 4 octets.

ZRPOS is how ZMODEM implements error-correction; if the sender receives a ZRPOS, it’ll include a file offset in the 4-octet sequence. That file offset is the receiver saying, “start sending from this offset in the file.” So when the receiver gets packets that fail the CRC check, it can ask the sender to start from the last-known “good” location in the file.

Why your rz is sending a second ZRPOS, though, I don’t know. Ordinarily over a reliable connection there’d only be 1 ZRPOS because there’s no chance a CRC check would fail.

I’m curious to know if that ZRPOS represents the current location in the file, or if your rz is actually asking the sender (zmodem.js) to go back for some reason … i.e., is it doing error-correction, or what?

Would you also try running rz with -vvvvvvvvv flags? It’ll be a lot of output, but it should at some level indicate why it’s sending another ZRPOS.

FGasper commented 4 years ago

Also, which OS are you running? Is the rz that you’re using a stock build, or did you build it yourself? Have you tried building lrzsz yourself and seeing if that resolves the problem?

Regardless, this is something that zmodem.js should accommodate; I’m just wondering why it happens in the first place.

FGasper commented 4 years ago

Try this: in zsession.js, change MAX_CHUNK_LENGTH to 1024.

I’m starting to think this is a bug in your rz. (Of course, that bug may be everywhere!) But over a reliable connection there should be no reason for that extra ZRPOS.

FGasper commented 4 years ago

Also, have you tried sending files that consist of pure ASCII? And/or smaller files?

There are sometimes issues with terminal configuration, which would make it a problem in your implementation.

Try this: create a file that consists of octets 0-255, then transfer that file via zmodem.js: by itself, and alongside a copy of itself. See if anything breaks.

FGasper commented 4 years ago

See if your pty has IEXTEN enabled or disabled. This setting affects whether octets 0x0f and 0x16 reach the terminal (and, thus, rz). If those are being blocked then that might explain the problem … though it wouldn’t explain why the timeout flag fixes the issue.

leffss commented 4 years ago

See if your pty has IEXTEN enabled or disabled. This setting affects whether octets 0x0f and 0x16 reach the terminal (and, thus, rz). If those are being blocked then that might explain the problem … though it wouldn’t explain why the timeout flag fixes the issue.

My server os is CentOS Linux release 7.5.1804 (Core).

The original lrzsz version was lrzsz-0.12.20-36.el7.x86_64,

if update to lrzsz-0.12.20-43.el8.x86_64, it also get that error.

When send small files like this:

[root@centos751 test3]# ll -h
total 204K
-rw------- 1 root root   63 Nov  4  2019 admin.py
-rw------- 1 root root   93 Nov  4  2019 apps.py
-rw------- 1 root root 1.9K Apr 15 14:25 deamon.ini
-rw------- 1 root root  120 Dec 24  2019 delete_makemigrations.sh
-rw------- 1 root root  722 Nov 13  2019 Dockerfile
-rw------- 1 root root  258 Aug  4 16:01 docker.sh
-rw------- 1 root root  105 Nov  4  2019 forms.py
-rw------- 1 root root 4.4K Jul 13 17:03 gunicorn.cfg
-rw------- 1 root root 2.7K Apr 13 14:34 init.py
-rw------- 1 root root  696 Apr 13 14:34 layer_group.py
-rw------- 1 root root  691 Apr 13 14:34 layer.py
-rw------- 1 root root   53 Sep 21  2019 makemigrations.sh
-rw------- 1 root root 2.1K Nov  4  2019 make_nginx.sh
-rw------- 1 root root  626 Nov  4  2019 manage.py
-rw------- 1 root root   46 Sep 21  2019 migrate.sh
-rw------- 1 root root   57 Nov  4  2019 models.py
-rw------- 1 root root  10K Jul  6 16:04 nginx.conf
-rw------- 1 root root  19K Aug  4 16:22 README.md
-rw------- 1 root root  779 Jun  1 11:37 requirements.txt
-rw------- 1 root root 1.3K Oct  9  2019 server.crt
-rw------- 1 root root 1.7K Oct  9  2019 server.key
-rw------- 1 root root  649 Nov  2  2019 sources.list
-rw------- 1 root root  560 Dec 24  2019 start_celery_beat_2.py
-rw------- 1 root root  556 Dec 24  2019 start_celery_beat.py
-rw------- 1 root root  638 Dec 24  2019 start_celery.py
-rw------- 1 root root  573 Dec 24  2019 start_daphne.py
-rw------- 1 root root  447 Dec 24  2019 start_docker_fast.py
-rw------- 1 root root  234 Dec  4  2019 start_docker_fast.sh
-rw------- 1 root root  442 Dec 24  2019 start_docker.py
-rw------- 1 root root  280 Dec  4  2019 start_docker.sh
-rw------- 1 root root  569 Apr 15 12:14 start_gunicorn.py
-rw------- 1 root root  15K Apr 27 16:27 telnet.py
-rw------- 1 root root 1.6K Apr 14 13:24 test.py
-rw------- 1 root root   60 Nov  4  2019 tests.py
-rw------- 1 root root  148 Nov  4  2019 urls.py
-rw------- 1 root root 1.7K Nov  6  2019 views.py
-rw------- 1 root root  11K Apr 13 14:46 websocket_layer.py
-rw------- 1 root root 6.5K Nov  4  2019 websocket.py
[root@centos751 test3]# 

it work well.

And I try to change MAX_CHUNK_LENGTH to 1024 and set IEXTEN to 0, it also get that error.

send RECEIVED HEADER ZRINIT 0,0,0,99
zsession.js:1386 SENDING OFFER {obj: File, name: "dig.rar", size: 1663966, mtime: Thu Aug 06 2020 17:21:05 GMT+0800 (中国标准时间), files_remaining: 27, …}
zsession.js:308 send SENDING HEADER ZFILE 0,0,0,0
zsession.js:1447 send -- HEADER PAYLOAD: end_ack 50
zsession.js:308 send RECEIVED HEADER ZRPOS 0,0,0,0
zsession.js:308 send SENDING HEADER ZDATA 0,0,0,0
zsession.js:308 send SENDING HEADER ZEOF 222,99,25,0
zsession.js:308 send RECEIVED HEADER ZRINIT 0,0,0,99
zsession.js:1386 SENDING OFFER {obj: File, name: "go1.13.5.windows-amd64.msi", size: 117338112, mtime: Thu Aug 06 2020 17:27:16 GMT+0800 (中国标准时间), files_remaining: 26, …}
zsession.js:308 send SENDING HEADER ZFILE 0,0,0,0
zsession.js:1447 send -- HEADER PAYLOAD: end_ack 72
zsession.js:308 send RECEIVED HEADER ZRPOS 0,0,0,0
zsession.js:308 send SENDING HEADER ZDATA 0,0,0,0
zsession.js:308 send RECEIVED HEADER ZRPOS 0,140,1,0
zsession.js:316 Unhandled header! ZRPOS_HEADER {_bytes4: Array(4)} null
_consume_header @ zsession.js:316
_parse_and_consume_header @ zsession.js:299
_consume_first @ zsession.js:1621
consume @ zsession.js:232
consume @ zsentry.js:228
wsOnMessage @ Console.vue?748d:600
Console.vue?748d:602 Error: Unhandled header: ZRPOS
    at ZmodemSendSession._consume_header (zsession.js:317)
    at ZmodemSendSession._parse_and_consume_header (zsession.js:299)
    at ZmodemSendSession._consume_first (zsession.js:1621)
    at ZmodemSendSession.consume (zsession.js:232)
    at ZmodemSentry.consume (zsentry.js:228)
    at VueComponent.wsOnMessage (Console.vue?748d:600)
zsession.js:308 send SENDING HEADER ZFIN 0,0,0,0
zsession.js:308 send RECEIVED HEADER ZRPOS 0,140,1,0
zsession.js:316 Unhandled header! ZRPOS_HEADER {_bytes4: Array(4)} {ZFIN: ƒ}
_consume_header @ zsession.js:316
_parse_and_consume_header @ zsession.js:299
_consume_first @ zsession.js:1621
consume @ zsession.js:232
consume @ zsentry.js:228
wsOnMessage @ Console.vue?748d:600
Console.vue?748d:602 Error: Unhandled header: ZRPOS
    at ZmodemSendSession._consume_header (zsession.js:317)
    at ZmodemSendSession._parse_and_consume_header (zsession.js:299)
    at ZmodemSendSession._consume_first (zsession.js:1621)
    at ZmodemSendSession.consume (zsession.js:232)
    at ZmodemSentry.consume (zsentry.js:228)
    at VueComponent.wsOnMessage (Console.vue?748d:600)
zsession.js:308 send SENDING HEADER ZFIN 0,0,0,0
zsession.js:308 send RECEIVED HEADER ZRPOS 0,140,1,0
zsession.js:316 Unhandled header! ZRPOS_HEADER {_bytes4: Array(4)} {ZFIN: ƒ}
_consume_header @ zsession.js:316
_parse_and_consume_header @ zsession.js:299
_consume_first @ zsession.js:1621
consume @ zsession.js:232
consume @ zsentry.js:228
wsOnMessage @ Console.vue?748d:600
Console.vue?748d:602 Error: Unhandled header: ZRPOS
    at ZmodemSendSession._consume_header (zsession.js:317)
    at ZmodemSendSession._parse_and_consume_header (zsession.js:299)
    at ZmodemSendSession._consume_first (zsession.js:1621)
    at ZmodemSendSession.consume (zsession.js:232)
    at ZmodemSentry.consume (zsentry.js:228)
    at VueComponent.wsOnMessage (Console.vue?748d:600)
zsession.js:308 send SENDING HEADER ZFIN 0,0,0,0
zsession.js:308 send RECEIVED HEADER ZRPOS 0,140,1,0

Since my program does not support rz -vvvvvvvvv now, I will test it again after modification.

leffss commented 4 years ago

See if your pty has IEXTEN enabled or disabled. This setting affects whether octets 0x0f and 0x16 reach the terminal (and, thus, rz). If those are being blocked then that might explain the problem … though it wouldn’t explain why the timeout flag fixes the issue.

rz -vvvvvvvvv result:

rz 0.12.20

mode:1
rz waiting to receive.zshhdr: ZRINIT 23000000Calling read: alarm=10  Readnum=8192 Read returned 27 bytes
zgethdr: ZSINIT 40000000zrdata: 1  ZCRCWzshhdr: ZACK 1Calling read: alarm=10  Readnum=8192 Read returned 98 bytes
zgethdr: ZFILE 0zrdata: 70  ZCRCWmode:3
zmanag=0, Lzmanag=0
zconv=1

Receiving: chrome79显示网站url插件.zip
zshhdr: ZRPOS 0Calling read: alarm=10  Readnum=8192 Read returned 15 bytes
zgethdr: ZDATA 0Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
zrdata: 8192  ZCRCG
...
...
...
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 2010 bytes
zrdata: 8192  ZCRCG
Bytes received: 165126144/165129052   BPS:912141 ETA 00:00  Calling read: alarm=10  Readnum=8192 Read returned 3715 bytes
zrdata: 2908  ZCRCGzrdata: 0  ZCRCEzgethdr: ZEOF 9d7ab5crzfile: normal EOF

Bytes received: 165129052/165129052   BPS:912156                
zshhdr: ZRINIT 63000000Calling read: alarm=10  Readnum=8192 Read returned 87 bytes
zgethdr: ZFILE 0zrdata: 63  ZCRCWmode:3
zmanag=0, Lzmanag=0
zconv=1

Receiving: VSCodeSetup-x64-1.41.1.exe
zshhdr: ZRPOS 0Calling read: alarm=10  Readnum=8192 Read returned 15 bytes
zgethdr: ZDATA 0Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 3682 bytes
zrdata: 8192  ZCRCG
Bytes received:    8192/59538136   BPS:134754 ETA 07:21  Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 3202 bytes
zrdata: 8192  ZCRCGCalling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 2936 bytes
zrdata: 8192  ZCRCGCalling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 3460 bytes
zrdata: 8192  ZCRCGCalling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 2932 bytes
zrdata: 8192  ZCRCGCalling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 3300 bytes
zrdata: 8192  ZCRCGCalling read: alarm=10  Readnum=8192 Read returned -1 bytes
errno=4:Interrupted system call
Retry 0: TIMEOUT
zshhdr: ZRPOS c000Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=1  Readnum=8192 Read returned 3270 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Retry 0: Garbage count exceeded
zshhdr: ZRPOS c000Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=1  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Retry 0: Garbage count exceeded
zshhdr: ZRPOS c000Calling read: alarm=1  Readnum=8192 Read returned 888 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 3704 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Retry 0: Garbage count exceeded
zshhdr: ZRPOS c000Retry 0: Bad CRC
Retry 0: Got ERROR
zgethdr: ERROR 6409147fzshhdr: ZRPOS c000Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 10 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Retry 0: Garbage count exceeded
zshhdr: ZRPOS c000Calling read: alarm=10  Readnum=8192 Read returned 3526 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=1  Readnum=8192 Read returned 4095 bytes
Retry 0: Garbage count exceeded
zshhdr: ZRPOS c000Calling read: alarm=10  Readnum=8192 Read returned 1081 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=1  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=1  Readnum=8192 Read returned 466 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Retry 0: Garbage count exceeded
zshhdr: ZRPOS c000Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=1  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=1  Readnum=8192 Read returned 57 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Retry 0: Garbage count exceeded
zshhdr: ZRPOS c000Calling read: alarm=1  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 389 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=1  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=1  Readnum=8192 Read returned 3297 bytes
Retry 0: Garbage count exceeded
zshhdr: ZRPOS c000Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=1  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=1  Readnum=8192 Read returned 3028 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Retry 0: Garbage count exceeded
zshhdr: ZRPOS c000Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=1  Readnum=8192 Read returned 4077 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=1  Readnum=8192 Read returned 4095 bytes
Retry 0: Garbage count exceeded
zshhdr: ZRPOS c000Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=1  Readnum=8192 Read returned 2840 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Retry 0: Bad CRC
Retry 0: Got ERROR
zgethdr: ERROR 575e0000zshhdr: ZRPOS c000Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=1  Readnum=8192 Read returned 4095 bytes
Retry 0: Garbage count exceeded
zshhdr: ZRPOS c000Retry 0: Bad CRC
Retry 0: Got ERROR
zgethdr: ERROR cccb01e2zshhdr: ZRPOS c000Calling read: alarm=10  Readnum=8192 Read returned 978 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Retry 0: Bad CRC
Retry 0: Got ERROR
zgethdr: ERROR 45867c4czshhdr: ZRPOS c000Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Retry 0: Bad CRC
Retry 0: Got ERROR
zgethdr: ERROR fc639332zshhdr: ZRPOS c000Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Calling read: alarm=10  Readnum=8192 Read returned 4095 bytes
Retry 0: Bad CRC
Retry 0: Got ERROR
zgethdr: ERROR f69bbbb2zshhdr: ZRPOS c000Retry 0: Bad CRC
Retry 0: Got ERROR
zgethdr: ERROR 35689823zshhdr: ZRPOS c000Retry 0: Bad CRC
Retry 0: Got ERROR
zgethdr: ERROR 3de28233zshhdr: ZRPOS c000Calling read: alarm=1  Readnum=8192 Read returned 4095 bytes
Retry 0: Bad CRC
Retry 0: Got ERROR
zgethdr: ERROR 538ffa6drzfile: zgethdr returned -1

rz: VSCodeSetup-x64-1.41.1.exe removed.
mode:0

Transfer incomplete
FGasper commented 4 years ago

@leffss Thank you.

So, this is what stands out to me:

zrdata: 8192  ZCRCGCalling read: alarm=10  Readnum=8192 Read returned -1 bytes
errno=4:Interrupted system call

Do you mind running strace on that rz process to see what signal is interrupting the read? I’m assuming it’s SIGALRM, in which case there’s a need to determine:

That said, this probably illustrates a use case for making zmodem.js recognize ZRPOS during transmission.

FGasper commented 4 years ago

I’ve looked this over. Recognizing ZRPOS will break some assumptions about the interaction between the Session classes and the Zmodem.Browser functions. That’s not the end of the world, but ideally then it’ll need some sort of callback mechanism to alert implementations of the repositioning.

Beyond that, the Transfer object will need to be made smart enough to abstract calls to send() and end() from the actual sending of subpackets. The caller (i.e., Zmodem.Browser) doesn’t expect to have to re-send(); while that contract could change, it seems more expedient to make Transfer handle any discrepancy between “last-added” position and “last-sent”. The only catch is that this will mean either buffering the entire file contents, or switching the subpackets to require the recipient to acknowledge receipt, which will slow things down a bit.

Unfortunately I can’t offer a timeline for when I may be able to do this work. For now I suggest telling your users to use the -O flag to avoid the timeouts. I’d also suggest investigating why rz is timing out; it shouldn’t be the browser, which makes me wonder if it’s your WebSocket server.

FGasper commented 4 years ago

@leffss Actually, on further thought this seems much simpler. Give the branch you’ve been using another try.

leffss commented 4 years ago

@leffss Actually, on further thought this seems much simpler. Give the branch you’ve been using another try.

Thanks very much. I think it is the browser that caused the timeout when transferring large files. I'll try to use FileReader to read segmentally, maybe it can solve this problem.

FGasper commented 4 years ago

@leffss Would you please, though, give the debug branch a shot with your code as you have it? I’d like to ensure that the ZRPOS is correctly ignored.

FGasper commented 4 years ago

Also, are you not using Zmodem.Browser? That implements the browser logic that you probably want.

leffss commented 4 years ago

Also, are you not using Zmodem.Browser? That implements the browser logic that you probably want.

Yes, I use Zmodem.Browser.send_files to upload files. I have modified this function by my logic, and now the problem is solved.

FGasper commented 4 years ago

@leffss Would you please run the branch that I’ve made against your unaltered code to verify that extra ZRPOS is now ignored?

I’ve put a fair bit of time into helping you investigate your problem. Now please help confirm that I’ve solved mine.

leffss commented 4 years ago

@leffss Would you please run the branch that I’ve made against your unaltered code to verify that extra ZRPOS is now ignored?

I’ve put a fair bit of time into helping you investigate your problem. Now please help confirm that I’ve solved mine.

2

FGasper commented 4 years ago

@leffss Thank you! I’ll push a new version that has the updated diagnostics.

Also, do you mind sharing the actual fix for your browser code? I’m curious to see what caused your browser to behave that way … looks like it sent 98,304 bytes then just hung.

leffss commented 4 years ago

@leffss Thank you! I’ll push a new version that has the updated diagnostics.

Also, do you mind sharing the actual fix for your browser code? I’m curious to see what caused your browser to behave that way … looks like it sent 98,304 bytes then just hung.

function send_files(session, files, options) {
    if (!options) options = {};

    //Populate the batch in reverse order to simplify sending
    //the remaining files/bytes components.
    var batch = [];
    var total_size = 0;
    for (var f=files.length - 1; f>=0; f--) {
        var fobj = files[f];
        total_size += fobj.size;
        batch[f] = {
            obj: fobj,
            name: fobj.name,
            size: fobj.size,
            mtime: new Date(fobj.lastModified),
            files_remaining: files.length - f,
            bytes_remaining: total_size,
        };
    }

    var file_idx = 0;
    function promise_callback() {
        var cur_b = batch[file_idx];

        if (!cur_b) {
            return Promise.resolve(); //batch done!
        }

        file_idx++;

        return session.send_offer(cur_b).then( function after_send_offer(xfer) {
            if (options.on_offer_response) {
                options.on_offer_response(cur_b.obj, xfer);
            }

            if (xfer === undefined) {
                return promise_callback();   //skipped
            }

            return new Promise( function(res) {
                var block = 1 * 1024 * 1024;
                var fileSize = cur_b.size;
                var fileLoaded = 0;
                var reader = new FileReader();
                reader.onerror = function reader_onerror(e) {
                    console.error('file read error', e);
                    throw ('File read error: ' + e);
                }
                function readBlob() {
                    var blob;
                    if (cur_b.obj.webkitSlice) {
                        blob = cur_b.obj.webkitSlice(fileLoaded, fileLoaded + block + 1);
                    } else if (cur_b.obj.mozSlice) {
                        blob = cur_b.obj.mozSlice(fileLoaded, fileLoaded + block + 1);
                    } else if (cur_b.obj.slice) {
                        blob = cur_b.obj.slice(fileLoaded, fileLoaded + block + 1);
                    } else {
                        blob = cur_b.obj;
                    }
                    reader.readAsArrayBuffer(blob);
                }
                var piece;
                reader.onload = function reader_onload(e) {
                    fileLoaded += e.total;
                    if (fileLoaded < fileSize) {
                        if (e.target.result) {
                            piece = new Uint8Array(e.target.result);
                            _check_aborted(session);
                            xfer.send(piece);
                            if (options.on_progress) {
                                options.on_progress(cur_b.obj, xfer, piece);
                            }
                        }
                        readBlob();
                    } else {
                        //
                        if (e.target.result) {
                            piece = new Uint8Array(e.target.result);
                            _check_aborted(session);
                            xfer.end(piece).then(function() {
                                if (options.on_progress && piece.length) {
                                    options.on_progress(cur_b.obj, xfer, piece);
                                }
                                if (options.on_file_complete) {
                                    options.on_file_complete(cur_b.obj, xfer);
                                }
                                res(promise_callback());
                            })
                        }
                    }
                }
                readBlob();
            } );
        } );
    }

    return promise_callback();
}
FGasper commented 4 years ago

@leffss I just looked this over. It looks like you’re accommodating cases where load fires before the file is fully read; I’m not sure on what browsers that happens, but the standard appears to describe load firing only at the (successful) end.

Anyway, I’m glad your issue is resolved. I’m going to close this issue. Thank you!

zxdong262 commented 4 years ago

@FGasper @leffss I have tried @leffss's send_files function, still same error, even try load the https://github.com/leffss/django-webssh/blob/master/webssh/static/zmodem/zmodem.devel.js, still get the same error, any ideas?

zxdong262 commented 4 years ago

@FGasper I think the root cause could be the send function is not real async, just wondering how to know the sending process is over.

FGasper commented 4 years ago

Please take this thread to Gitter. Thank you!

leffss commented 4 years ago

@zxdong262 https://github.com/leffss/gowebssh

zxdong262 commented 4 years ago

@leffss @FGasper I tried https://github.com/leffss/gowebssh, it works, so I think it must be my code's problem.

panda521119 commented 3 years ago

When I use 'rz' to upload a file,I can not cancel

FGasper commented 3 years ago

@panda521119 This is not the forum to use to request help. Please read the docs. Thank you!

I’m unsubscribing from this issue and will not respond further here.