mirror of
https://github.com/dschmenk/PLASMA.git
synced 2025-02-15 13:33:41 +00:00
HTTP server updates from David Finnigan
This commit is contained in:
parent
b3064d4a00
commit
dae713bd25
@ -1,6 +1,13 @@
|
|||||||
//
|
//
|
||||||
// HTTP Daemon
|
// HTTP Daemon
|
||||||
//
|
//
|
||||||
|
// with these updates by D. Finnigan on 12 Nov 15:
|
||||||
|
// - revised 404 and 400 responses
|
||||||
|
// - split 200 OK response headers
|
||||||
|
// - added get_file_info() call
|
||||||
|
// - check for binary files and set Content-Type accordingly
|
||||||
|
// still todo: output base filename for Content-Disposition header
|
||||||
|
//
|
||||||
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
|
||||||
@ -32,15 +39,28 @@ word socketHTTP
|
|||||||
byte[65] prefix
|
byte[65] prefix
|
||||||
byte perr
|
byte perr
|
||||||
word filebuff, iobuff
|
word filebuff, iobuff
|
||||||
byte hello = "Apple II Web Server\n"
|
byte fileInfo[12] = 0 // used for get_file_info()
|
||||||
|
byte hello = "Apple II Web Server - 12 Nov 15\n"
|
||||||
byte defhtml = "INDEX.HTML"
|
byte defhtml = "INDEX.HTML"
|
||||||
|
byte[200] okhdr // combined response header
|
||||||
//
|
//
|
||||||
// HTTP response
|
// HTTP response codes
|
||||||
|
// For the 4xx codes, if you change the body, make sure to update the Content-Length too
|
||||||
|
byte httpOK = "HTTP/1.1 200 OK\n\r"
|
||||||
|
byte httpBAD = "HTTP/1.1 400 Bad Request\n\rContent-Type: text/plain\n\rContent-Length: 17\n\r\n\r400 Bad Request\n\r"
|
||||||
|
byte httpNOTFOUND = "HTTP/1.1 404 Not Found\n\rStatus: 404 Not Found\n\rContent-Type: text/plain\n\rContent-Length: 28\n\r\n\r404 Error: File not found.\n\r"
|
||||||
//
|
//
|
||||||
byte httpOK = "HTTP/1.1 200 OK\n\rContent-Type: text/html\n\rContent-Length: "
|
// HTTP response headers
|
||||||
|
//
|
||||||
|
byte httpContentType = "Content-Type: "
|
||||||
|
byte httpContentLen = "Content-Length: "
|
||||||
|
byte httpContentAttach = "Content-Disposition: attachment; filename="
|
||||||
byte httpEnd = "\n\r\n\r"
|
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"
|
//
|
||||||
byte httpNOFILE = "HTTP/1.1 404 NOTFOUND\n\rContent-Type: text/plain\n\rContent-Length: 24\n\r\n\rError:File not found.\n\r"
|
// MIME content types
|
||||||
|
//
|
||||||
|
byte mimeTextHtml = "text/html"
|
||||||
|
byte mimeOctetStream = "application/octet-stream"
|
||||||
//
|
//
|
||||||
// ProDOS routines
|
// ProDOS routines
|
||||||
//
|
//
|
||||||
@ -100,6 +120,14 @@ def get_eof(refnum)
|
|||||||
syscall($D1, @params)
|
syscall($D1, @params)
|
||||||
return params:2
|
return params:2
|
||||||
end
|
end
|
||||||
|
def get_file_info(path)
|
||||||
|
|
||||||
|
fileInfo.0 = 10 // param count
|
||||||
|
fileInfo:1 = path // path name
|
||||||
|
|
||||||
|
perr = syscall($C4, @fileInfo)
|
||||||
|
return perr
|
||||||
|
end
|
||||||
//
|
//
|
||||||
// DEBUG
|
// DEBUG
|
||||||
//
|
//
|
||||||
@ -186,9 +214,8 @@ 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, refnum
|
byte i, refnum, err
|
||||||
byte[65] filename
|
byte[65] filename
|
||||||
byte[128] okhdr
|
|
||||||
byte[8] lenstr
|
byte[8] lenstr
|
||||||
word url, filelen
|
word url, filelen
|
||||||
|
|
||||||
@ -203,15 +230,15 @@ def servHTTP(remip, remport, lclport, data, len, param)
|
|||||||
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 // maximum ProDOS path
|
||||||
fin
|
fin
|
||||||
for i = 4 to len
|
for i = 4 to len // get ProDOS path from URL
|
||||||
if data->[i] <= ' '
|
if data->[i] <= ' '
|
||||||
data->3= i - 4
|
data->3= i - 4
|
||||||
url = data + 3
|
url = data + 3
|
||||||
if url->1 == '/'
|
if url->1 == '/'
|
||||||
if url->0 == 1
|
if url->0 == 1
|
||||||
url = @defhtml
|
url = @defhtml // Is this a directory with no file given? Use index.html
|
||||||
else
|
else
|
||||||
url->1 = url->0 - 1
|
url->1 = url->0 - 1
|
||||||
url = url + 1
|
url = url + 1
|
||||||
@ -220,19 +247,52 @@ def servHTTP(remip, remport, lclport, data, len, param)
|
|||||||
strcat(@filename, @prefix, url)
|
strcat(@filename, @prefix, url)
|
||||||
putc('G');putc('E');putc('T');putc(':')
|
putc('G');putc('E');putc('T');putc(':')
|
||||||
puts(@filename);putln
|
puts(@filename);putln
|
||||||
refnum = open(@filename, iobuff)
|
|
||||||
if refnum
|
// Get file info
|
||||||
filelen = get_eof(refnum)
|
//puts("getting file info "); // debug
|
||||||
lenstr = itos(@lenstr + 1, filelen) - (@lenstr + 1)
|
get_file_info(@filename)
|
||||||
strcat(@okhdr, @httpOK, @lenstr)
|
|
||||||
strcat(@okhdr, @okhdr, @httpEnd)
|
|
||||||
//dumpchars(@okhdr + 1, okhdr)
|
refnum = open(@filename, iobuff) // try to open this file with ProDOS
|
||||||
iNet:sendTCP(socketHTTP, @okhdr + 1, okhdr)
|
if refnum // file was opened OK
|
||||||
sendFile(refnum, socketHTTP, filelen)
|
filelen = get_eof(refnum) // get length of file for Content-Length
|
||||||
close(refnum)
|
lenstr = itos(@lenstr + 1, filelen) - (@lenstr + 1)
|
||||||
else
|
strcat(@okhdr, @httpOK, @httpContentLen)
|
||||||
iNet:sendTCP(socketHTTP, @httpNOFILE + 1, httpNOFILE)
|
strcat(@okhdr, @okhdr, @lenstr)
|
||||||
fin
|
strcat(@okhdr, @okhdr, "\n\r")
|
||||||
|
|
||||||
|
// Content type header
|
||||||
|
// is this a text file?
|
||||||
|
if fileInfo.4 == $03 OR fileInfo.4 == $04
|
||||||
|
//puts(@mimeTextHtml) // debug
|
||||||
|
strcat(@okhdr, @okhdr, @httpContentType)
|
||||||
|
strcat(@okhdr, @okhdr, @mimeTextHtml)
|
||||||
|
|
||||||
|
else // send as binary attachment
|
||||||
|
//puts(@mimeOctetStream) // debug
|
||||||
|
|
||||||
|
strcat(@okhdr, @okhdr, @httpContentType)
|
||||||
|
strcat(@okhdr, @okhdr, @mimeOctetStream)
|
||||||
|
strcat(@okhdr, @okhdr, "\n\r")
|
||||||
|
|
||||||
|
// and send filename too
|
||||||
|
strcat(@okhdr, @okhdr, @httpContentAttach)
|
||||||
|
|
||||||
|
// todo: get the base filename...
|
||||||
|
|
||||||
|
fin
|
||||||
|
|
||||||
|
strcat(@okhdr, @okhdr, @httpEnd)
|
||||||
|
|
||||||
|
//dumpchars(@okhdr + 1, okhdr) // debug
|
||||||
|
|
||||||
|
iNet:sendTCP(socketHTTP, @okhdr + 1, okhdr) // send HTTP response header to client
|
||||||
|
sendFile(refnum, socketHTTP, filelen) // send file data to client
|
||||||
|
close(refnum)
|
||||||
|
else // file couldn't be opened, so return 404 on this
|
||||||
|
puts("404 Not Found");putln // debug
|
||||||
|
iNet:sendTCP(socketHTTP, @httpNOTFOUND + 1, httpNOTFOUND)
|
||||||
|
fin // if refnum
|
||||||
return
|
return
|
||||||
fin
|
fin
|
||||||
next
|
next
|
||||||
|
Loading…
x
Reference in New Issue
Block a user