A2osX/BIN/HTTPGET.S.txt
2021-07-24 22:42:23 +02:00

803 lines
13 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

NEW
AUTO 3,1
.LIST OFF
.OP 65C02
.OR $2000
.TF bin/httpget
*--------------------------------------
.INB inc/macros.i
.INB inc/a2osx.i
.INB inc/mli.i
.INB inc/mli.e.i
.INB inc/eth.i
.INB inc/libtcpip.i
.INB inc/net.http.i
*--------------------------------------
TIMEOUT.MAX .EQ 250 25 sec.
*--------------------------------------
.DUMMY
.OR ZPBIN
ZS.START
ZPIPCfgPtr .BS 2
ZPHostPtr .BS 2
ZPPtr .BS 2
ArgIndex .BS 1
hSocket .BS 1
hReqBuf .BS 1
ZPReqBufPtr .BS 2
ZPReqBufLen .BS 2
bHeader .BS 1
TimeOut .BS 1
bURI .BS 1
hEncodedBuf .BS 1
ZPEncodedBufPtr .BS 2
ZPEncodedBufLen .BS 2
hSendBuf .BS 1
ZPSendBufPtr .BS 2
hRespBuf .BS 1
ZPRespBufPtr .BS 2
ZPRespBufLen .BS 2
hFile .BS 1
ZPFileName .BS 2
ZS.END .ED
*--------------------------------------
* File Header (16 Bytes)
*--------------------------------------
CS.START cld
jmp (.1,x)
.DA #$61 6502,Level 1 (65c02)
.DA #1 BIN Layout Version 1
.DA #S.PS.F.EVENT S.PS.F
.DA #0
.DA CS.END-CS.START Code Length To Relocate
.DA DS.END-DS.START Data Segment to Allocate
.DA #64 SS
.DA #ZS.END-ZS.START Zero Page Size
.DA 0
*--------------------------------------
.1 .DA CS.INIT
.DA CS.RUN
.DA CS.DOEVENT
.DA CS.QUIT
L.LIBTCPIP .DA LIBTCPIP
L.SA.LOCAL .DA SA.LOCAL
L.SA.REMOTE .DA SA.REMOTE
L.SA.REMOTE.AD .DA SA.REMOTE+S.SOCKADDR.ADDR
L.MSG.IPKO .DA MSG.IPKO
L.MSG.USAGE .DA MSG.USAGE
L.MSG.CRLF .DA MSG.CRLF
L.MSG.UNKNOWN .DA MSG.UNKNOWN
L.MSG.CONNECT .DA MSG.CONNECT
L.MSG.SKTKO .DA MSG.SKTKO
L.MSG.CONNECTED .DA MSG.CONNECTED
L.MSG.SKTERR .DA MSG.SKTERR
L.MSG.IOERR .DA MSG.IOERR
L.MSG.FileLength .DA MSG.FileLength
L.MSG.Progress .DA MSG.Progress
L.HTTP.GET .DA HTTP.GET
.DA 0
*--------------------------------------
CS.INIT >LDYA L.LIBTCPIP
>SYSCALL LoadLib
bcs .9
sta hLIBTCPIP
.9 rts
*--------------------------------------
CS.RUN >LIBCALL hLIBTCPIP,LIBTCPIP.GETCFG is TCPIP loaded ?
>STYA ZPIPCfgPtr
lda (ZPIPCfgPtr) Configured ?
bmi CS.RUN.IPOK
>LDYA L.MSG.IPKO
>SYSCALL PutS
lda #E.SYN
sec
rts
CS.RUN.IPOK ldy #S.IPCFG.IP+3
ldx #3
.1 lda (ZPIPCfgPtr),y
sta SA.LOCAL+S.SOCKADDR.ADDR,x
dey
dex
bpl .1
jsr CS.RUN.GETNEXTARG
bcs .9
>STYA ZPHostPtr
jsr Init.TimeOut
.2 >PUSHW L.SA.REMOTE.AD
>PUSHW ZPHostPtr
>LIBCALL hLIBTCPIP,LIBTCPIP.HST.GetByName
bcc CS.RUN.HOSTOK
>SLEEP
lda TimeOut
bne .2
>PUSHW L.MSG.UNKNOWN
>PUSHW ZPHostPtr
>PUSHBI 2
>SYSCALL PrintF
bra CS.RUN.ESYN
.9 >PUSHW L.MSG.USAGE
>PUSHBI 0
>SYSCALL PrintF
CS.RUN.ESYN lda #E.SYN
sec
CS.RUN.RTS rts
*--------------------------------------
CS.RUN.HOSTOK jsr CS.RUN.GETNEXTARG
bcc .10
.8 jmp CS.RUN.ARGSOK
.10 >STYA ZPPtr
lda (ZPPtr)
cmp #'-'
beq .1
>LDYA ZPPtr
>SYSCALL AToI
bcs CS.RUN.RTS
>STYA SA.REMOTE+S.SOCKADDR.PORT
jsr CS.RUN.GETNEXTARG
bcs .8
>STYA ZPPtr
lda (ZPPtr)
cmp #'-'
bne CS.RUN.ESYN
.1 ldy #1
lda (ZPPtr),y
cmp #'a'
bcc .11
cmp #'z'+1
bcs .11
eor #$20
.11 cmp #'U'
bne .2
bit bURI
bmi CS.RUN.ESYN
jsr CS.RUN.GETNEXTARG
.9 bcs CS.RUN.ESYN
>STYA ZPReqBufPtr
>SYSCALL StrLen
>STYA ZPReqBufLen
sec
ror bURI
bra CS.RUN.HOSTOK
.2 cmp #'F'
bne .3
bit bURI
bmi CS.RUN.ESYN
jsr CS.RUN.GETNEXTARG
bcs .9
>SYSCALL LoadTxtFile
bcs .9
>STYA ZPReqBufLen
stx hReqBuf
>SYSCALL GetMemPtr
>STYA ZPReqBufPtr
sec
ror bURI
jmp CS.RUN.HOSTOK
.3 cmp #'O'
bne .9
inc ArgIndex
lda ArgIndex
>SYSCALL ArgV
bcs .9
>STYA ZPFileName
jmp CS.RUN.HOSTOK
*--------------------------------------
CS.RUN.GETNEXTARG
inc ArgIndex
lda ArgIndex
>SYSCALL ArgV
rts
*--------------------------------------
CS.RUN.ARGSOK >PUSHW L.MSG.CONNECT
ldx #0
.1 >PUSHB SA.REMOTE+S.SOCKADDR.ADDR,x
inx
cpx #4
bne .1
>PUSHW SA.REMOTE+S.SOCKADDR.PORT
>PUSHW ZPHostPtr
>PUSHBI 8
>SYSCALL PrintF
CS.RUN.OPENSKT >PUSHBI S.SOCKET.T.SEQPKT
>PUSHBI 0 no protocol
>LIBCALL hLIBTCPIP,LIBTCPIP.Socket
bcs .9
sta hSocket
>PUSHB hSocket
>PUSHW L.SA.LOCAL
>LIBCALL hLIBTCPIP,LIBTCPIP.Bind
bcc .1
.9 pha
>LDYA L.MSG.SKTKO
>SYSCALL PutS
pla
sec
.99 rts
.1 jsr Init.TimeOut
.2 >SLEEP
>PUSHB hSocket
>PUSHW L.SA.REMOTE
>LIBCALL hLIBTCPIP,LIBTCPIP.Connect
bcc .3
cmp #ERR.SKT.NOCONN
bne .9
lda TimeOut
bne .2
lda #ERR.SKT.NOCONN
bra .9
.3 >SLEEP
lda hSocket
>LIBCALL hLIBTCPIP,LIBTCPIP.Recv
bcc .7
cmp #E.NODATA
beq .8
ldx TimeOut
bne .3
lda #ERR.SKT.NOCONN
bra .9
.7 >SYSCALL Freemem
.8 >LDYA L.MSG.CONNECTED
>SYSCALL PutS
>SLEEP
CS.RUN.GET jsr CS.RUN.ENCODE
bcs .99
jsr CS.RUN.REQUEST
bcs .99
>LDYA ZPFileName
beq .1
>PUSHYA
>PUSHBI O.CREATE+O.WRONLY+O.TRUNC
>PUSHBI 0 TYPE
>PUSHWZ AUXTYPE
>SYSCALL FOpen
bcs .9
sta hFile
.1 jsr CS.RUN.RESPONSE
bcs .99
.9 lda #0
sec
.99 rts
*--------------------------------------
CS.RUN.SKTERR pha
>PUSHW L.MSG.SKTERR
pla
pha
>PUSHA
>PUSHBI 1
>SYSCALL PrintF
pla
sec
rts
*--------------------------------------
CS.RUN.IOERR pha
>PUSHW L.MSG.IOERR
pla
pha
>PUSHA
>PUSHBI 1
>SYSCALL PrintF
pla
sec
rts
*--------------------------------------
CS.RUN.ENCODE >LDYA ZPReqBufPtr
>STYA ZPPtr
inc ZPEncodedBufLen for ending \0
.1 lda (ZPPtr)
beq .4
inc ZPPtr
bne .2
inc ZPPtr+1
.2 jsr CS.RUN.TOENCODE if CS 3 bytes, if CC 1 byte
lda #1
bcc .3
inc
.3 adc ZPEncodedBufLen
sta ZPEncodedBufLen
bcc .1
inc ZPEncodedBufLen+1
bra .1
*--------------------------------------
.4 >LDYA ZPEncodedBufLen
>SYSCALL GetMem
bcs .9
>STYA ZPEncodedBufPtr
>STYA ZPPtr
stx hEncodedBuf
.5 lda (ZPReqBufPtr)
beq .8
inc ZPReqBufPtr
bne .6
inc ZPReqBufPtr+1
.6 jsr CS.RUN.TOENCODE
bcc .7
jsr CS.RUN.ADDBYTETOBUF
bra .5
.7 jsr CS.RUN.ADDTOBUF
bra .5
.8 sta (ZPPtr) ending \0
clc
.9 rts
*--------------------------------------
CS.RUN.TOENCODE ldx #URI.ToEncode.Cnt-1
.1 cmp URI.ToEncode,x
beq .9 CS
dex
bpl .1
clc
.9 rts
*--------------------------------------
CS.RUN.ADDBYTETOBUF
pha
lda #'%'
jsr CS.RUN.ADDTOBUF
pla
pha
lsr
lsr
lsr
lsr
ora #$30
cmp #$3A
bcc .1
adc #6
.1 jsr CS.RUN.ADDTOBUF
pla
and #$0F
ora #$30
cmp #$3A
bcc CS.RUN.ADDTOBUF
adc #6
*--------------------------------------
CS.RUN.ADDTOBUF sta (ZPPtr)
inc ZPPtr
bne .8
inc ZPPtr+1
.8 rts
*--------------------------------------
CS.RUN.REQUEST jsr Init.TimeOut
>LDYAI 1024
>SYSCALL GetMem
bcs .9
>STYA ZPSendBufPtr
stx hSendBuf
>PUSHYA
>PUSHW L.HTTP.GET
>PUSHW ZPEncodedBufPtr
>PUSHW ZPHostPtr
>PUSHBI 4
>SYSCALL SPrintF
bcs .90
pha
>PUSHB hSocket
>PUSHW ZPSendBufPtr
pla
>PUSHYA Byte count
>LIBCALL hLIBTCPIP,LIBTCPIP.Send
.90 php
pha
lda hSendBuf
>SYSCALL FreeMem
pla
plp
.9
CS.RUN.REQUEST.RTS
rts
*--------------------------------------
CS.RUN.RESPONSE jsr Init.TimeOut
.1 >SLEEP
lda hSocket
>LIBCALL hLIBTCPIP,LIBTCPIP.Recv
bcc .2
cmp #E.NODATA
bne .80
jsr CS.RUN.CtrlC
bcs CS.RUN.REQUEST.RTS
lda TimeOut
bne .1
bit bHeader
bmi .1
.80 jmp .8
.2 jsr CS.RUN.GETRESPONSE
bit bHeader
bmi .6
jsr CS.RUN.GETHEADER
sec
ror bHeader
.6 lda hFile
bne .7
ldy #S.PS.hStdOut
lda (pPS),y
.7 >PUSHA
>PUSHW ZPRespBufPtr
>PUSHW ZPRespBufLen
>SYSCALL FWrite
bcs .9
lda hRespBuf
stz hRespBuf
>SYSCALL FreeMem
lda ZPRespBufLen
clc
adc Received
sta Received
lda ZPRespBufLen+1
adc Received+1
sta Received+1
bcc .70
inc Received+2
bne .70
inc Received+3
.70 >PUSHW L.MSG.Progress
>PUSHL Received
>PUSHBI 4
>SYSCALL PrintF
bcs .9
jmp CS.RUN.RESPONSE
.8 bit bHeader
bpl .99
>PUSHW L.MSG.CRLF
>PUSHBI 0
>SYSCALL PrintF
jsr CS.RUN.CHECKLEN
bcc .9
.99 lda #MLI.E.IO
sec
.9 rts
*--------------------------------------
CS.RUN.GETRESPONSE
sta hRespBuf
>SYSCALL GetMemPtr
>STYA ZPRespBufPtr
ldy #S.IP.TOTAL.LENGTH+1
lda (ZPRespBufPtr),y
sec
sbc #S.TCP-S.ETH.EII
sta ZPRespBufLen
dey
lda (ZPRespBufPtr),y
sbc /S.TCP-S.ETH.EII
sta ZPRespBufLen+1
lda ZPRespBufPtr
clc
adc #S.TCP
sta ZPRespBufPtr
bcc .8
inc ZPRespBufPtr+1
.8 rts
*--------------------------------------
CS.RUN.GETHEADER
.1 ldy #$ff
.2 iny
lda (ZPRespBufPtr),y
eor #C.CR
bne .2
sta (ZPRespBufPtr),y
iny skip CR
iny skip LF
sty ArgIndex
>LDYA ZPRespBufPtr
>STYA ZPPtr
lda ZPRespBufLen
sec
sbc ArgIndex
sta ZPRespBufLen
bcs .3
dec ZPRespBufLen+1
.3 lda ArgIndex
tay
clc
adc ZPRespBufPtr
sta ZPRespBufPtr
bcc .4
inc ZPRespBufPtr+1
.4 dey
dey
beq .8
ldy #$ff
.5 iny
lda (ZPPtr),y
cmp HEAD.ContentLength,y
bne .1
cmp #C.SPACE
bne .5
tya
sec skip SPACE
adc ZPPtr
tay
lda ZPPtr+1
adc #0
>SYSCALL AToL
>PULLL Length
>PUSHW L.MSG.FileLength
>PUSHL Length
>PUSHBI 4
>SYSCALL PrintF
jmp .1
.8 clc
.9 rts
*--------------------------------------
CS.RUN.CHECKLEN ldx #3
sec
.1 lda Received,x
eor Length,x
bne .9
dex
bpl .1
clc
.9 rts
*--------------------------------------
CS.RUN.CtrlC ldy #S.PS.hStdIn
lda (pPS),y
>SYSCALL FEOF
bcs .8
tay
bne .8 CC
>SYSCALL GetChar
bcs .9
cmp #$03 Ctrl-C
beq .9 CS
.8 clc
.9 rts
*--------------------------------------
CS.DOEVENT lda (pEvent)
bpl .9 is it a TIMER event?
lda TimeOut
beq .9
dec TimeOut
.9 sec do not discard TIMER event
rts
*--------------------------------------
CS.QUIT lda hSocket
beq .1
>LIBCALL hLIBTCPIP,LIBTCPIP.Shutdown
.1 lda hReqBuf
beq .2
>SYSCALL FreeMem
.2 lda hEncodedBuf
beq .3
>SYSCALL FreeMem
.3 lda hRespBuf
beq .4
>SYSCALL FreeMem
.4 lda hFile
beq .5
>SYSCALL FClose
.5 lda hLIBTCPIP
beq .8
>SYSCALL UnloadLib
.8 clc
rts
*--------------------------------------
Init.TimeOut lda #TIMEOUT.MAX
sta TimeOut
rts
*--------------------------------------
CS.END
LIBTCPIP .AZ "libtcpip"
hLIBTCPIP .BS 1
MSG.IPKO .AZ "TCP/IP Not Loaded/Configured."
MSG.USAGE .AS "Usage : HTTPGET <ip|host> [port]\r\n"
.AS " -U : Url\r\n"
.AS " -F : UrlFile\r\n"
.AS " -O : OutputFile"
MSG.CRLF .AZ "\r\n"
MSG.UNKNOWN .AZ "%s: Unknown host\r\n"
MSG.CONNECT .AZ "Connecting to %d.%d.%d.%d:%D (%s)..."
MSG.SKTKO .AZ "Failed to Open Socket."
MSG.CONNECTED .AZ "Connected."
MSG.SKTERR .AZ "Socket Error : $%h\r\n"
MSG.IOERR .AZ "I/O Error : $%h\r\n"
MSG.FileLength .AZ "File Length : %10u Bytes\r\n"
MSG.Progress .AZ "\rReceived : %10u"
*--------------------------------------
SA.LOCAL .DA #AF.INET S.SOCKADDR.AF
.BS 1
.BS 4 S.SOCKADDR.ADDR
.BS 2 S.SOCKADDR.PORT
*--------------------------------------
SA.REMOTE .DA #AF.INET S.SOCKADDR.AF
.BS 1
.BS 4 S.SOCKADDR.ADDR
.DA TCP.PORT.HTTP
*--------------------------------------
URI.ToEncode .DA #C.LF,#C.CR,#C.SPACE,#'"'
.AS "%-.\^_`{|}~"
URI.ToEncode.Cnt .EQ *-URI.ToEncode
*--------------------------------------
HEAD.ContentLength .AZ "Content-Length: "
*--------------------------------------
HTTP.GET .AS "GET /%s HTTP/1.1"
.DA #C.CR,#C.LF
.AS "User-Agent: A2osX.HTTPGET"
.DA #C.CR,#C.LF
.AS "Host: %s"
.DA #C.CR,#C.LF
.AS "Connection: close"
.DA #C.CR,#C.LF
.DA #C.CR,#C.LF
.DA #0
*--------------------------------------
Received .BS 4
Length .BS 4
*--------------------------------------
.DUMMY
.OR 0
DS.START
DS.END .ED
*--------------------------------------
MAN
SAVE usr/src/bin/httpget.s
ASM