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

View File

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

View File

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