1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2024-07-05 04:28:57 +00:00

Working HTTP server

This commit is contained in:
dschmenk 2015-02-12 13:00:44 -08:00
parent 9686ef8ca6
commit 970ae32b88
3 changed files with 132 additions and 73 deletions

View File

@ -474,27 +474,28 @@ def wizSendUDP(wiz, ipdst, portdst, data, len)
//
// Wait for Tx room
//
repeat
txrr = peekregw(wizregs + WIZ_SnTXRD)
txwr = peekregw(wizregs + WIZ_SnTXWR)
until txrr == txwr
repeat; until peekregw(wizregs + WIZ_SnFSR) >= len
//
// Calc new write ptr, check for split
//
txwr = peekregw(wizregs + WIZ_SnTXWR)
txrr = txwr & WIZ_TXMASK
if txrr + len > WIZ_TXSIZE
splitlen = WIZ_TXSIZE - txrr
pokeregs(wizdata + txrr, data, splitlen)
pokeregs(wizdata, data + splitlen, len - splitlen)
else
pokeregs(wizdata + txrr, data, len)
fin
//
// Set destination address/port
//
pokeregs(wizregs + WIZ_SnDIPR, ipdst, IP4ADR_SIZE)
pokeregw(wizregs + WIZ_SnDPORT, portdst)
//
// Calc new write ptr, check for split
// Update write pointer and send
//
txwr = txrr + len
if txwr >= WIZ_TXSIZE
splitlen = WIZ_TXSIZE - txrr
pokeregs(wizdata + txrr, data, splitlen)
pokeregs(wizdata, data + splitlen, len - splitlen)
else
pokeregs(wizdata + txrr, data, len)
fin
pokeregw(wizregs + WIZ_SnTXWR, txwr)
pokeregw(wizregs + WIZ_SnTXWR, txwr + len)
pokereg(wizregs + WIZ_SnCR, $20) // SEND
end
//
@ -508,7 +509,7 @@ def wizOpenUDP(localport, callback, param)
//
// Look for an existing notification on localport
//
putc('O')
//putc('O')
wiz = @wizChannel
for i = 1 to MAX_WIZ_CHANNELS
if wiz->channel_proto == IP_PROTO_UDP and wiz=>channel_lclport == localport
@ -531,7 +532,7 @@ def wizOpenUDP(localport, callback, param)
return 0
fin
fin
putc('0' + i);putln
//putc('0' + i);putln
//
// Fill in this channel and open it
//
@ -548,19 +549,19 @@ end
// Close UDP port
//
def wizCloseUDP(wiz)
putc('S')
//putc('S')
if isuge(wiz, @wizChannel) and isult(wiz, @wizChannel + MAX_WIZ_CHANNELS * t_channel)
//
// Clear notiications on this port
//
if wiz->channel_proto == WIZ_PROTO_UDP
putc('1' + ((wiz=>channel_regs - WIZ_SREGS) >> 8));putln
//putc('1' + ((wiz=>channel_regs - WIZ_SREGS) >> 8));putln
wiz->channel_proto = WIZ_PROTO_CLOSED
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
return 0
fin
fin
putc('!');putln
//putc('!');putln
//
// Invalid port
//
@ -576,7 +577,7 @@ def wizListenTCP(lclport, callback, param)
//
// Look for an existing notification on localport
//
putc('L')
//putc('L')
wiz = @wizChannel
for i = 1 to MAX_WIZ_CHANNELS
if wiz->channel_proto == WIZ_PROTO_TCP and wiz->channel_state == TCP_STATE_LISTEN and wiz=>channel_lclport == lclport
@ -599,7 +600,7 @@ def wizListenTCP(lclport, callback, param)
return 0
fin
fin
putc('0' + i);putln
//putc('0' + i);putln
//
// Fill in this channel and open it
//
@ -611,8 +612,10 @@ def wizListenTCP(lclport, callback, param)
wiz=>channel_lclport = lclport
wiz=>channel_recv_func = callback
wiz=>channel_recv_parm = param
pokeregw(wiz=>channel_regs + WIZ_SnPORT, lclport)
pokereg(wiz=>channel_regs + WIZ_SnMR, $01) // TCP protocol
pokeregw(wiz=>channel_regs + WIZ_SnPORT, lclport)
pokereg(wiz=>channel_regs + WIZ_SnCR, $01) // OPEN
while peekreg(wiz=>channel_regs + WIZ_SnSR) <> $13; loop // Wait for init
pokereg(wiz=>channel_regs + WIZ_SnCR, $02) // LISTEN
return wiz
end
@ -659,10 +662,12 @@ def wizConnectTCP(remip, remport, lclport, callback, param)
wiz=>channel_lclport = lclport
wiz=>channel_recv_func = callback
wiz=>channel_recv_parm = param
pokereg(wiz=>channel_regs + WIZ_SnMR, $01) // TCP protocol
pokeregs(wiz=>channel_regs + WIZ_SnDIPR, remip, IP4ADR_SIZE)
pokeregw(wiz=>channel_regs + WIZ_SnDPORT, remport)
pokeregw(wiz=>channel_regs + WIZ_SnPORT, lclport)
pokereg(wiz=>channel_regs + WIZ_SnMR, $01) // TCP protocol
pokereg(wiz=>channel_regs + WIZ_SnCR, $01) // OPEN
while peekreg(wiz=>channel_regs + WIZ_SnSR) <> $13; loop // Wait for init
pokereg(wiz=>channel_regs + WIZ_SnCR, $04) // CONNECT
return wiz
end
@ -673,27 +678,31 @@ def wizSendTCP(wiz, data, len)
word wizregs, wizdata, txrr, txwr, splitlen
if wiz->channel_state <> TCP_STATE_OPEN; return -1; fin
//putc('W');puti(len);putc(':')
wizregs = wiz=>channel_regs
wizdata = wiz=>channel_txmem
//
// Wait for Tx room
//
repeat
txrr = peekregw(wizregs + WIZ_SnTXRD)
txwr = peekregw(wizregs + WIZ_SnTXWR)
until txrr == txwr
repeat; until peekregw(wizregs + WIZ_SnFSR) >= len
//
// Calc new write ptr, check for split
//
txwr = txrr + len
if txwr >= WIZ_TXSIZE
txwr = peekregw(wizregs + WIZ_SnTXWR)
txrr = txwr & WIZ_TXMASK
if txrr + len > WIZ_TXSIZE
splitlen = WIZ_TXSIZE - txrr
pokeregs(wizdata + txrr, data, splitlen)
pokeregs(wizdata, data + splitlen, len - splitlen)
else
//putc('(');puti(splitlen);putc(',');puti(len-splitlen);putc(')')
else
pokeregs(wizdata + txrr, data, len)
fin
pokeregw(wizregs + WIZ_SnTXWR, txwr)
//puth(txrr);putc('-');putc('>');puth(txwr+len);putln
//
// Update write pointer and send
//
pokeregw(wizregs + WIZ_SnTXWR, txwr + len)
pokereg(wizregs + WIZ_SnCR, $20) // SEND
end
//
@ -728,7 +737,7 @@ def wizServiceIP
ir = peekreg(WIZ_IR)
if ir and ir <> $FF // Ignore spurious read of IR
putc('I');putb(ir)
//putc('I');putb(ir)
wiz = @wizChannel
for i = 0 to 3
when ir & (1 << i)
@ -742,7 +751,7 @@ def wizServiceIP
when wiz->channel_proto
is WIZ_PROTO_TCP
if sir & $01
putc('C')
//putc('C')
//
// Connect TCP socket
//
@ -754,34 +763,35 @@ def wizServiceIP
wiz->channel_state = TCP_STATE_OPEN
break
otherwise
putc('?')
//putc('?')
wend
fin
if sir & $04
putc('R')
//putc('R')
//
// Receive TCP packet
//
rxlen = peekregw(wizregs + WIZ_SnRSR)
rxrr = peekregw(wizregs + WIZ_SnRXRD)
rxwr = rxrr + rxlen
rxwr = rxrr & WIZ_RXMASK
rxpkt = heapalloc(rxlen)
if rxwr >= WIZ_RXSIZE
putc('!')
splitlen = WIZ_RXSIZE - rxrr
peekregs(wizdata + rxrr, rxpkt, splitlen)
//puti(rxlen);putc(':')
if rxwr + rxlen > WIZ_RXSIZE
splitlen = WIZ_RXSIZE - rxwr
peekregs(wizdata + rxwr, rxpkt, splitlen)
peekregs(wizdata, rxpkt + splitlen, rxlen - splitlen)
//putc('(');puti(splitlen);putc(',');puti(rxlen-splitlen);putc(')')
else
peekregs(wizdata + rxrr, rxpkt, rxlen)
peekregs(wizdata + rxwr, rxpkt, rxlen)
fin
putc('=');putip(@wiz=>channel_remip);putc(':');puti(wiz=>channel_remport);putln
pokeregw(wizregs + WIZ_SnRXRD, rxwr)
//puth(rxwr);putc('-');putc('>');puth(rxwr+rxlen);putln
pokeregw(wizregs + WIZ_SnRXRD, rxrr + rxlen)
pokereg(wizregs + WIZ_SnCR, $40) // RECV
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,rxpkt,rxlen,wiz=>channel_recv_parm)
heaprelease(rxpkt)
fin
if sir & $02
putc('S')
//putc('S')
//
// Close TCP socket
//
@ -795,11 +805,11 @@ def wizServiceIP
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
break
otherwise
putc('?')
//putc('?')
wend
fin
if sir & $08
putc('T')
//putc('T')
//
// Timeout on TCP socket
//
@ -815,10 +825,16 @@ def wizServiceIP
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
break
otherwise
putc('?')
//putc('?')
wend
fin
break
//if sir & $10
//putc('W');putc('O');putc('K');puth(peekregw(wiz=>channel_regs+WIZ_SnTXWR));putln
//
// Write TCP socket OK
//
//fin
break
is WIZ_PROTO_UDP
//putc('U');putb(sir)
if sir & $04
@ -828,20 +844,20 @@ def wizServiceIP
//
rxlen = peekregw(wizregs + WIZ_SnRSR)
rxrr = peekregw(wizregs + WIZ_SnRXRD)
rxwr = rxrr + rxlen
rxwr = rxrr & WIZ_RXMASK
rxpkt = heapalloc(rxlen)
if rxwr >= WIZ_RXSIZE
putc('!')
splitlen = WIZ_RXSIZE - rxrr
peekregs(wizdata + rxrr, rxpkt, splitlen)
if rxwr + rxlen >= WIZ_RXSIZE
//putc('!')
splitlen = WIZ_RXSIZE - rxwr
peekregs(wizdata + rxwr, rxpkt, splitlen)
peekregs(wizdata, rxpkt + splitlen, rxlen - splitlen)
else
peekregs(wizdata + rxrr, rxpkt, rxlen)
peekregs(wizdata + rxwr, rxpkt, rxlen)
fin
//putc('=');putip(rxpkt);putc(' ');puti(rxlen)
//putc('/');puti(swab(rxpkt=>6))
//putc(' ');puth(rxrr);putc(' ');puth(rxwr);putln
pokeregw(wizregs + WIZ_SnRXRD, rxwr)
pokeregw(wizregs + WIZ_SnRXRD, rxrr + rxlen)
pokereg(wizregs + WIZ_SnCR, $40) // RECV
wiz=>channel_recv_func(rxpkt,swab(rxpkt=>4),rxpkt+8,rxlen-8,wiz=>channel_recv_parm)
heaprelease(rxpkt)
@ -921,6 +937,8 @@ for slot = $F0 downto $90 step $10
//
pokeregs(WIZ_SHAR, @wizMAC, 6) // MAC addr
pokeregw(WIZ_RTR, 5000) // Timeout period to 500ms
pokereg(WIZ_RMSR, $55) // 2K Rx memory/channel
pokereg(WIZ_TMSR, $55) // 2K Tx memory/channel
//
// Fill channel structure
//

View File

@ -4,6 +4,7 @@
import cmdsys
predef syscall, call, getc, gets, putc, puts, putln
predef memset, memcpy, modaddr, modexec
predef isugt, isuge, isult, isule
predef heapmark, heapallocalign, heapalloc, heaprelease
byte MACHID
end
@ -36,18 +37,9 @@ byte defhtml = "INDEX.HTML"
//
// HTTP response
//
byte httpOK = "HTTP/1.1 200 OK\n"
byte = "Content-Type: text/html\n"
byte = "Content-Length: "
byte httpLen = " \n"
byte = ""
byte httpBAD = "HTTP/1.1 404 NOTFOUND\n"
byte = "Content-Type: text/plain\n"
byte = "Content-Length: 12\n"
byte = "\n"
byte = "Bad Request\n"
byte = ""
byte[] httpBAD_end
byte httpOK = "HTTP/1.1 200 OK\n\rContent-Type: text/html\n\rContent-Length: "
byte httpEnd = "\n\r\n\r"
byte httpBAD = "HTTP/1.1 404 NOTFOUND\n\rContent-Type: text/plain\n\rContent-Length: 12\n\r\n\rBad Request\n\r"
//
// ProDOS routines
//
@ -97,6 +89,16 @@ def read(refnum, buff, len)
perr = syscall($CA, @params)
return params:6
end
def get_eof(refnum)
byte params[5]
params.0 = 2
params.1 = refnum
params:2 = 0
params.4 = 0
syscall($D1, @params)
return params:2
end
//
// DEBUG
//
@ -138,6 +140,14 @@ def dumpbytes(buf, len)
fin
next
end
def dumpchars(buf, len)
word i
len = len - 1
for i = 0 to len
putc(buf->[i])
next
end
//
// String functions
//
@ -158,21 +168,38 @@ def itos(dst, i)
return dst + 1
end
//
// Send the file contents
//
def sendFile(fd, socket, len)
while isuge(len, 1024)
read(fd, filebuff, 1024)
len = len - 1024
iNet:sendTCP(socket, filebuff, 1024)
loop
if len
read(fd, filebuff, len)
iNet:sendTCP(socket, filebuff, len)
fin
end
//
// Serve HTTP requests
//
def servHTTP(remip, remport, lclport, data, len, param)
byte i
byte i, refnum
byte[65] filename
word url
byte[128] okhdr
byte[8] lenstr
word url, filelen
//
// Parse HTTP request
//
if len > 0
//dumpchars(data, len)
//
// Better be 'GET'
//
if data->0 == 'G' and data->1 == 'E' and data->2 == 'T' and data=>3 == ' '
if data->0 == 'G' and data->1 == 'E' and data->2 == 'T' and data->3 == ' '
len = len - 1
if len > 64
len = 64
@ -190,12 +217,26 @@ def servHTTP(remip, remport, lclport, data, len, param)
fin
fin
strcat(@filename, @prefix, url)
putc('G');putc('E');putc('T');putc(':')
puts(@filename);putln
refnum = open(@filename, iobuff)
if refnum
filelen = get_eof(refnum)
lenstr = itos(@lenstr + 1, filelen) - (@lenstr + 1)
strcat(@okhdr, @httpOK, @lenstr)
strcat(@okhdr, @okhdr, @httpEnd)
dumpchars(@okhdr + 1, okhdr)
iNet:sendTCP(socketHTTP, @okhdr + 1, okhdr)
sendFile(refnum, socketHTTP, filelen)
close(refnum)
else
iNet:sendTCP(socketHTTP, @httpBAD + 1, httpBAD)
fin
return
fin
next
else
iNet:sendTCP(socketHTTP, @httpBAD, @httpBAD_end - @httpBAD)
iNet:sendTCP(socketHTTP, @httpBAD + 1, httpBAD)
fin
else
iNet:closeTCP(socketHTTP)

View File

@ -168,7 +168,7 @@ t_token scan(void)
constval = 0x0D;
break;
case 'r':
constval = '\r';
constval = 0x0A;
break;
case 't':
constval = '\t';
@ -212,7 +212,7 @@ t_token scan(void)
*scanpos = 0x0D;
break;
case 'r':
*scanpos = '\r';
*scanpos = 0x0A;
break;
case 't':
*scanpos = '\t';