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 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.G CLN.hSocket >SYSCALL GetMemPtr >STYA ZPSktPtr >PUSHW L.MSG.INCOMING >PUSHB.G 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.G CLN.hSocket >PUSHBI 1 >SYSCALL printf >LDA.G 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 txa >STA.G REP.hBuf .10 >STZ.G REQ.FullPath >STA.G REQ.hReq >STA.G REQ.KeepAlive >STA.G REQ.hFile .1 >SLEEP >LDA.G 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.G REQ.hReq >SYSCALL FreeMem >STZ.G 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.G CLN.hSocket >LIBCALL hLIBTCPIP,LIBTCPIP.Send .8 >LDA.G REQ.KeepAlive beq .99 jmp .10 .98 >LDA.G REQ.hReq beq .99 >SYSCALL FreeMem .99 >LDA.G REP.hBuf >SYSCALL freemem rts *-------------------------------------- CS.RUN.REQ.GetReq >STA.G REQ.hReq >SYSCALL GetMemPtr >STYA ZPRequestPtr >PUSHW L.MSG.REQ >PUSHB.G REQ.hReq >PUSHB.G 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.G 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 txa >STA.G 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.G REQ.MimeType clc .9 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 bcs .9 bra .1 .8 cmp #MLI.E.EOF bne .9 clc .9 php pha >LDA.G REQ.hFile >SYSCALL FClose pla plp rts *-------------------------------------- CS.RUN.SendBuf >PUSHYA >PUSHW ZPRepPtr >LDA.G 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.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 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 "404:NOT FOUND" .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 CLN.hSocket .BS 1 REQ.hReq .BS 1 REQ.hFile .BS 1 REQ.MimeType .BS 1 REQ.KeepAlive .BS 1 REP.hBuf .BS 1 DS.END .ED *-------------------------------------- MAN SAVE usr/src/sbin/httpd.s ASM