A2osX/SBIN/HTTPD.S.txt
2020-08-09 21:47:42 +02:00

822 lines
14 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 sbin/httpd
*--------------------------------------
.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 30 30 sec.
CONN.MAX .EQ 16
*--------------------------------------
.DUMMY
.OR ZPBIN
ZS.START
ZPPtr1 .BS 2
ZPPtr2 .BS 2
ZPSktPtr .BS 2
hFile .BS 1
hLineBuf .BS 1
hSrvSocket .BS 1
TimeOut .BS 1
hSrvName .BS 1
ZPSrvNamePtr .BS 2
hRootdir .BS 1
ZPRootDirPtr .BS 2
ZPRequestPtr .BS 2
ZPnRequestLen .BS 2
ZPLinePtr .BS 2
ZPRepPtr .BS 2
CLN.hSocket .BS 1
REP.hBuf .BS 1
REQ.hFile .BS 1
REQ.KeepAlive .BS 1
REQ.MimeType .BS 1
REQ.hReq .BS 1
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
.DA #0
.DA CS.END-CS.START CS
.DA DS.END-DS.START DS
.DA #64 SS
.DA #ZS.END-ZS.START Zero Page Size
.DA 0
*--------------------------------------
* Relocation Table
*--------------------------------------
.1 .DA CS.INIT
.DA CS.RUN
.DA CS.DOEVENT
.DA CS.QUIT
L.LIBTCPIP .DA LIBTCPIP
L.ETCHTTPDCONF .DA ETCHTTPDCONF
L.KEYWORDS.CONF .DA KEYWORDS.CONF
J.KEYWORDS.CONF .DA CS.RUN.CONF.SERVERNAME
.DA CS.RUN.CONF.LISTEN
.DA CS.RUN.CONF.DOCUMENTROOT
L.SA.Local .DA SA.Local
L.MSG.TCPWAIT .DA MSG.TCPWAIT
L.MSG.TCPIPERR .DA MSG.TCPIPERR
L.MSG.INITCONF .DA MSG.INITCONF
L.MSG.INITOK .DA MSG.INITOK
L.MSG.SKTERR .DA MSG.SKTERR
L.MSG.INCOMING .DA MSG.INCOMING
L.MSG.REQ .DA MSG.REQ
L.MSG.FILE .DA MSG.FILE
L.MSG.SKTCLOSE .DA MSG.SKTCLOSE
L.KEYWORDS.REQ .DA KEYWORDS.REQ
J.KEYWORDS.REQ .DA CS.RUN.REQ.GET
L.INDEX.HTML .DA INDEX.HTML
L.MIME.TYPES .DA MIME.TYPES
T.MIME .DA MIME.HTML
.DA MIME.TXT
.DA MIME.TTF
.DA MIME.ICO
.DA MIME.PNG
.DA MIME.JPG
L.MIME.DEFAULT .DA MIME.DEFAULT
L.HTTP.200 .DA HTTP.200
L.HTTP.404 .DA HTTP.404
.DA 0
*--------------------------------------
CS.INIT >LDYA L.LIBTCPIP
>SYSCALL LoadLib
bcs .9
sta hLIBTCPIP
.9 rts
*--------------------------------------
CS.RUN >LDYA L.MSG.TCPWAIT
>SYSCALL PutS
lda #TIMEOUT.MAX
sta TimeOut
.1 >SLEEP
>LIBCALL hLIBTCPIP,LIBTCPIP.GETCFG is TCPIP loaded ?
bcs .99
>STYA ZPPtr1
lda (ZPPtr1) Configured ?
bmi CS.RUN.INIT
lda Timeout
bcs .99
ldy #S.PS.hStdIn
lda (pPS),y
>SYSCALL feof
bcs CS.RUN.RTS I/O err
tay
bne .1
>SYSCALL GetChar
bcs CS.RUN.RTS
cmp #3 Ctrl-C
bne .1
sec
rts
.99 >LDYA L.MSG.TCPIPERR
>SYSCALL PutS
CS.RUN.SYN
lda #E.SYN
sec
CS.RUN.RTS rts
*--------------------------------------
CS.RUN.INIT ldx #3
ldy #S.IPCFG.IP+3
.1 lda (ZPPtr1),y
sta SA.LOCAL+S.SOCKADDR.ADDR,x
dey
dex
bpl .1
>LDYAI 256
>SYSCALL GetMem
bcs CS.RUN.RTS
>STYA ZPLinePtr
stx hLineBuf
>PUSHW L.MSG.INITCONF
>PUSHW L.ETCHTTPDCONF
>PUSHBI 2
>SYSCALL PrintF
bcs CS.RUN.RTS
jsr CS.RUN.CONF
bcs CS.RUN.RTS
>PUSHBI 0 no protocol
lda #S.SOCKET.T.SEQPKT
>LIBCALL hLIBTCPIP,LIBTCPIP.Socket
bcs CS.RUN.RTS
sta hSrvSocket
>PUSHW L.SA.LOCAL
lda hSrvSocket
>LIBCALL hLIBTCPIP,LIBTCPIP.Bind
bcs CS.RUN.ERR
lda hSrvSocket
>LIBCALL hLIBTCPIP,LIBTCPIP.Listen
bcs CS.RUN.ERR
>PUSHW L.MSG.INITOK
>PUSHW SA.LOCAL+S.SOCKADDR.PORT
>PUSHW ZPRootDirPtr
>PUSHBI 4
>SYSCALL PrintF
*--------------------------------------
CS.RUN.LOOP >SLEEP
jsr CS.RUN.SERVER
bcs CS.RUN.ERR
bra CS.RUN.LOOP
CS.RUN.ERR >LDYA L.MSG.SKTERR
>SYSCALL PutS
lda #E.SYN
sec
rts
*--------------------------------------
CS.RUN.CONF >PUSHW L.ETCHTTPDCONF
>PUSHBI O.RDONLY+O.TEXT
>PUSHBI S.FI.T.TXT
>PUSHWZ
>SYSCALL FOpen
bcs .99
sta hFile
.1 >PUSHWI 256
>PUSHW ZPLinePtr
lda hFile
>SYSCALL fgets
bcs .8
tya
beq .1
lda (ZPLinePtr)
cmp #'#'
beq .1
>LDYA L.KEYWORDS.CONF
>STYA ZPPtr1
ldx #0
.2 ldy #0
.3 lda (ZPPtr1),y
cmp (ZPLinePtr),y
bne .4
iny
cmp #C.SPACE
bne .3
jsr CS.RUN.CONF.JMP
bcc .1
bra .97
.4 inx
inx
ldy #0
.5 iny
lda (ZPPtr1),y
cmp #C.SPACE
bne .5
tya
sec
adc ZPPtr1
sta ZPPtr1
bcc .6
inc ZPPtr1+1
.6 lda (ZPPtr1)
bne .2
.97 lda #E.SYN
.98 pha
jsr .8
pla
sec
.99 rts
.8 lda hFile
>SYSCALL FClose
rts
*--------------------------------------
CS.RUN.CONF.JMP tya
clc
adc ZPLinePtr
sta ZPPtr1
tay
lda #0
adc ZPLinePtr+1
sta ZPPtr1+1
jmp (J.KEYWORDS.CONF,x)
CS.RUN.CONF.SERVERNAME
>SYSCALL StrDup
bcs .9
>STYA ZPSrvNamePtr
stx hSrvName
.9 rts
CS.RUN.CONF.LISTEN
>SYSCALL atoi
bcs .9
>STYA SA.LOCAL+S.SOCKADDR.PORT
.9 rts
CS.RUN.CONF.DOCUMENTROOT
>PUSHYA
>PUSHWI 0 Allocate
>SYSCALL RealPath
bcs .9
>STYA ZPRootDirPtr
stx hRootdir
.9 rts
*--------------------------------------
CS.RUN.SERVER lda hSrvSocket
>LIBCALL hLIBTCPIP,LIBTCPIP.accept
bcs .8
sta CLN.hSocket
>SYSCALL GetMemPtr
>STYA ZPSktPtr
>PUSHW L.MSG.INCOMING
>PUSHB CLN.hSocket
ldx #3
ldy #S.SOCKET.REM.ADDR
.1 >PUSHB (ZPSktPtr),y
iny
dex
bpl .1
>PUSHBI 5
>SYSCALL PrintF
jsr CS.RUN.CLIENT
>PUSHW L.MSG.SKTCLOSE
>PUSHB CLN.hSocket
>PUSHBI 1
>SYSCALL printf
lda CLN.hSocket
>LIBCALL hLIBTCPIP,LIBTCPIP.Shutdown
.8 clc
.9
CS.RUN.SERVER.RTS
rts
*--------------------------------------
CS.RUN.CLIENT >LDYAI 1024
>SYSCALL GetMem
bcs CS.RUN.SERVER.RTS
>STYA ZPRepPtr
stx REP.hBuf
.10 >STZ.G REQ.FullPath
stz REQ.hReq
stz REQ.KeepAlive
stz REQ.hFile
.1 >SLEEP
lda CLN.hSocket
>LIBCALL hLIBTCPIP,LIBTCPIP.Recv
bcc .2
tay
beq .1
jmp .99
.2 jsr CS.RUN.REQ.GetReq
.3 jsr CS.RUN.REQ.GetLine
bcs .4
>LDYA ZPLinePtr
>STYA ZPPtr2
>LDYA L.KEYWORDS.REQ
jsr CS.RUN.GET.KW
bcs .3
jsr CS.RUN.REQ.JMP
bcc .3
bcs .98
.4 lda REQ.hReq
>SYSCALL FreeMem
stz REQ.hReq
>LDA.G REQ.FullPath
beq .9
jsr CS.RUN.OpenFile
bcs .9
jsr CS.RUN.SendFile
bcs .99
bra .8
.9 >PUSHWI HTTP.404.len
>PUSHW L.HTTP.404
lda CLN.hSocket
>LIBCALL hLIBTCPIP,LIBTCPIP.Send
.8 bit REQ.KeepAlive
bpl .99
jmp .10
.98 lda REQ.hReq
beq .99
>SYSCALL FreeMem
.99 lda REP.hBuf
>SYSCALL freemem
rts
*--------------------------------------
CS.RUN.REQ.GetReq
sta REQ.hReq
>SYSCALL GetMemPtr
>STYA ZPRequestPtr
>PUSHW L.MSG.REQ
>PUSHB REQ.hReq
>PUSHB CLN.hSocket
>PUSHBI 2
>SYSCALL printf
ldy #S.IP.TOTAL.LENGTH+1
lda (ZPRequestPtr),y
sec
sbc #S.TCP-S.IP
eor #$ff
sta ZPnRequestLen
dey
lda (ZPRequestPtr),y
sbc /S.TCP-S.IP
eor #$ff
sta ZPnRequestLen+1
lda ZPRequestPtr
clc
adc #S.TCP
sta ZPRequestPtr
bcc .8
inc ZPRequestPtr+1
.8 rts
*--------------------------------------
CS.RUN.REQ.GetLine
ldy #0
.1 inc ZPnRequestLen
bne .2
inc ZPnRequestLen+1
beq .9
.2 lda (ZPRequestPtr)
inc ZPRequestPtr
bne .21
inc ZPRequestPtr+1
.21 cmp #C.CR
bne .4
inc ZPnRequestLen
bne .3
inc ZPnRequestLen+1
beq .9
.3 lda (ZPRequestPtr)
inc ZPRequestPtr
bne .31
inc ZPRequestPtr+1
.31 eor #C.LF
bne .9
sta (ZPLinePtr),y Y,A = StrLen
clc
rts
.4 sta (ZPLinePtr),y
iny
bra .1
.9 sec
rts
*--------------------------------------
CS.RUN.OpenFile >PUSHW L.MSG.FILE
>PUSHB CLN.hSocket
>PUSHEA.G REQ.FullPath
>PUSHBI 3
>SYSCALL printf
>PUSHEA.G REQ.FullPath
>PUSHBI O.RDONLY
>PUSHBI 0 type
>PUSHWZ Aux type
>SYSCALL FOpen
bcs .9
stx REQ.hFile
>PUSHA
>PUSHEA.G REQ.Stat
>SYSCALL FStat
>LEA.G REQ.FullPath
>STYA ZPPtr2
ldx #$ff
ldy #$ff
.1 iny
lda (ZPPtr2),y
beq .2
cmp #'.'
bne .1
tya
tax
bra .1
.2 txa
bpl .3
lda #MIME.DEFAULT.ID
bra .8
.3 sec
adc ZPPtr2
sta ZPPtr2
bcc .4
inc ZPPtr2+1
.4 >LDYA L.MIME.TYPES
jsr CS.RUN.GET.KW
txa
.8 sta REQ.MimeType
clc
.9 rts
*--------------------------------------
CS.RUN.SendFile >PUSHW ZPRepPtr
>PUSHW L.HTTP.200
ldx REQ.MimeType
>PUSHW T.MIME,x
>PUSHL.G REQ.Stat+S.STAT.SIZE
>PUSHBI 6
>SYSCALL SPrintf
bcs .9
jsr CS.RUN.SendBuf Y,A = car count
.1 >PUSHWI 1024
>PUSHW ZPRepPtr
lda REQ.hFile
>SYSCALL fread
bcs .8
jsr CS.RUN.SendBuf
bcs .9
bra .1
.8 cmp #MLI.E.EOF
bne .9
clc
.9 php
pha
lda REQ.hFile
>SYSCALL FClose
pla
plp
rts
*--------------------------------------
CS.RUN.SendBuf >PUSHYA
>PUSHW ZPRepPtr
lda CLN.hSocket
>LIBCALL hLIBTCPIP,LIBTCPIP.Send
rts
*--------------------------------------
CS.RUN.REQ.JMP jmp (J.KEYWORDS.REQ,x)
*--------------------------------------
CS.RUN.REQ.GET ldy #0
.1 iny
lda (ZPPtr2),y
eor #C.SPACE
bne .1
sta (ZPPtr2),y
lda (ZPPtr2)
cmp #'/'
bne .4
>PUSHW ZPRootDirPtr
>LEA.G REQ.FullPath
>SYSCALL StrCpy
ldy #1
lda (ZPPtr2),y
bne .2
>LDYA L.INDEX.HTML
bra .3
.2 >LDYA ZPPtr2
.3 >PUSHYA
>LEA.G REQ.FullPath
>SYSCALL StrCat
rts
.4 >PUSHW ZPPtr2
>PUSHEA.G REQ.FullPath
>SYSCALL realpath
.9 rts
*--------------------------------------
CS.RUN.REQ.Connection
lda (ZPPtr2)
eor #'k'
beq .1
lda #$ff
.1 sta REQ.KeepAlive
clc
rts
*--------------------------------------
CS.RUN.GET.KW >STYA ZPPtr1
ldx #0
.2 ldy #$ff
.3 iny
lda (ZPPtr1),y
cmp (ZPPtr2),y
bne .4
cmp #0
beq .33
cmp #C.SPACE
bne .3
.33 tya
sec
adc ZPPtr2
sta ZPPtr2
bcc .8
inc ZPPtr2+1
.8 clc
rts
.4 inx
inx
ldy #0
.5 iny
lda (ZPPtr1),y
bne .5
tya
sec
adc ZPPtr1
sta ZPPtr1
bcc .6
inc ZPPtr1+1
.6 lda (ZPPtr1)
bne .2
sec
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 hSrvSocket
beq .1
>LIBCALL hLIBTCPIP,LIBTCPIP.Shutdown
.1 lda hLineBuf
beq .2
>SYSCALL FreeMem
.2
lda hLIBTCPIP
beq .8
>SYSCALL UnloadLib
.8 clc
rts
*--------------------------------------
CS.END
*--------------------------------------
hLIBTCPIP .BS 1
LIBTCPIP .AZ "libtcpip"
ETCHTTPDCONF .AZ "${BOOT}etc/httpd.conf"
*--------------------------------------
KEYWORDS.CONF .AS "ServerName "
.AS "Listen "
.AS "DocumentRoot "
.DA #0
*--------------------------------------
MSG.TCPWAIT .AZ "HTTPD:Waiting for TCP/IP initializing..."
MSG.TCPIPERR .AZ "HTTPD:TCP/IP Not initialized properly."
MSG.INITCONF .AZ "HTTPD:Reading %s file...\r\n"
MSG.INITOK .AZ "HTTPD:Listening on port %D, root dir: %s.\r\n"
MSG.SKTERR .AZ "HTTPD:Skt Bind Error."
MSG.INCOMING .AZ "HTTPD:Skt $%h Opened From %d.%d.%d.%d\r\n"
MSG.REQ .AZ "HTTPD:Req $%h From Skt $%h\r\n"
MSG.FILE .AZ "HTTPD:Skt $%h File %s\r\n"
MSG.SKTCLOSE .AZ "HTTPD:Skt $%h Close\r\n"
*--------------------------------------
KEYWORDS.REQ .AS "GET "
.AS "Connection: "
.DA #0
*--------------------------------------
INDEX.HTML .AS "/index." html
*--------------------------------------
MIME.TYPES .AZ "html"
.AZ "txt"
.AZ "ttf"
.AZ "ico"
.AZ "png"
.AZ "jpg"
.DA #0
MIME.HTML .AZ "text/html"
MIME.TXT .AZ "text/plain"
MIME.TTF .AZ "font/truetype"
MIME.ICO .AZ "image/vnd.microsoft.icon" "image/x-icon"
MIME.PNG .AZ "image/png"
MIME.JPG .AZ "image/jpeg"
MIME.DEFAULT .AZ "application/octet-stream"
MIME.DEFAULT.ID .EQ 12
*--------------------------------------
HTTP.200 .AS "HTTP/1.1 200 OK"
.DA #C.CR,#C.LF
.AS "Server: A2osX-HTTPD 0.94"
.DA #C.CR,#C.LF
.AS "Content-Type: %s"
.DA #C.CR,#C.LF
.AS "Content-Length: %u"
.DA #C.CR,#C.LF
.DA #C.CR,#C.LF
.DA #0
*--------------------------------------
HTTP.404 .AS "HTTP/1.1 404 Not Found"
.DA #C.CR,#C.LF
.AS "Server: A2osX-HTTPD 0.94"
.DA #C.CR,#C.LF
.AS "Content-Type: text/html"
.DA #C.CR,#C.LF
.AS "Content-Length: 47"
.DA #C.CR,#C.LF
.AS "Connection: Close"
.DA #C.CR,#C.LF
.DA #C.CR,#C.LF
.AS "<HTML><BODY><B>404:NOT FOUND<B></BODY></HTML>"
.DA #C.CR,#C.LF
HTTP.404.len .EQ *-HTTP.404
*--------------------------------------
SA.LOCAL .DA #AF.INET S.SOCKADDR.AF
.BS 1
.BS 4 S.SOCKADDR.ADDR
.DA TCP.PORT.HTTP
*--------------------------------------
.DUMMY
.OR 0
DS.START
REQ.FullPath .BS MLI.MAXPATH+1
REQ.Stat .BS S.STAT
DS.END
.ED
*--------------------------------------
MAN
SAVE usr/src/sbin/httpd.s
ASM