A2osX/SBIN/HTTPD.S.txt

804 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
hStr .BS 1
hSrvSocket .BS 1
TimeOut .BS 1
hSrvName .BS 1
ZPSrvNamePtr .BS 2
hRootdir .BS 1
ZPRootDirPtr .BS 2
hClntSocket .BS 1
ZPRequestPtr .BS 2
ZPnRequestLen .BS 2
ZPLinePtr .BS 2
ZPRepPtr .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
.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.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.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 hStr
>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.SEQPACKET
>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
.9 >LDYA L.MSG.SKTERR
>SYSCALL PutS
lda #E.SYN
sec
CS.RUN.ERR 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 hClntSocket
>SYSCALL GetMemPtr
>STYA ZPSktPtr
>PUSHW L.MSG.INCOMING
ldx #3
ldy #S.SOCKET.REM.ADDR
>PUSHB hClntSocket
.1 >PUSHB (ZPSktPtr),y
iny
dex
bpl .1
>PUSHBI 5
>SYSCALL PrintF
jsr CS.RUN.CLIENT
.8 clc
.9 rts
*--------------------------------------
CS.RUN.CLIENT >STZ.G REQ.KeepAlive
>STA.G REQ.FullPath
>STA.G REQ.hFile
>STA.G REQ.hBuf
.1 >SLEEP
lda hClntSocket
>LIBCALL hLIBTCPIP,LIBTCPIP.Recv
bcc .2
tay
beq .1
jmp .80
.2 jsr CS.RUN.REQ.GetFrame
.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 .9
.4 >LDA.G REQ.FullPath
beq .9
>LDYAI 1024
>SYSCALL GetMem
bcs .9
>STYA ZPRepPtr
txa
>STA.G REQ.hBuf
jsr CS.RUN.OpenFile
bcs .9
jsr CS.RUN.GetMime
bcs .9
jsr CS.RUN.SendFile
bcc .5
.9 >PUSHWI HTTP.404.len
>PUSHW L.HTTP.404
lda hClntSocket
>LIBCALL hLIBTCPIP,LIBTCPIP.Send
bcs .80
* >STZ.G REQ.KeepAlive
.5 >LDA.G REQ.hFile
beq .6
>SYSCALL FClose
.6 >LDA.G REQ.hBuf
beq .7
>SYSCALL freemem
.7 >LDA.G REQ.hFrame
beq .8
>SYSCALL FreeMem
.8 >LDA.G REQ.KeepAlive
beq .80
jmp CS.RUN.CLIENT
.80 lda hClntSocket
>LIBCALL hLIBTCPIP,LIBTCPIP.Shutdown
.99 rts
*--------------------------------------
CS.RUN.REQ.GetFrame
>STA.G REQ.hFrame
>SYSCALL GetMemPtr
>STYA ZPRequestPtr
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 >LEA.G REQ.FullPath
>SYSCALL puts
>PUSHEA.G REQ.FullPath
>PUSHBI O.RDONLY
>PUSHBI 0 type
>PUSHWZ Aux type
>SYSCALL FOpen
bcs .9
txa
>STA.G REQ.hFile
>PUSHA
>PUSHEA.G REQ.Stat
>SYSCALL FStat
.9 rts
*--------------------------------------
CS.RUN.GetMime >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.G REQ.MimeType
clc
rts
*--------------------------------------
CS.RUN.SendFile >PUSHW ZPRepPtr
>PUSHW L.HTTP.200
>LDA.G REQ.MimeType
tax
>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.G REQ.hFile
>SYSCALL fread
bcs .8
jsr CS.RUN.SendBuf
bcc .1
rts
.8 cmp #MLI.E.EOF
bne .9
clc
.9 rts
*--------------------------------------
CS.RUN.SendBuf >PUSHYA
>PUSHW ZPRepPtr
lda hClntSocket
>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.G 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 hStr
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:Listen Error."
MSG.INCOMING .AZ "HTTPD:Incoming Connection [SKT=%h] From : %d.%d.%d.%d\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
REQ.hFrame .BS 1
REQ.hFile .BS 1
REQ.hBuf .BS 1
REQ.MimeType .BS 1
REQ.KeepAlive .BS 1
DS.END
.ED
*--------------------------------------
MAN
SAVE usr/src/sbin/httpd.s
ASM