1
0
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:
dschmenk 2015-11-13 12:13:32 -08:00
parent b3064d4a00
commit dae713bd25
2 changed files with 83 additions and 23 deletions

BIN
HTTPD.PO

Binary file not shown.

View File

@ -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