A few change to make it more customizable

and prepare integration to EiffelWebReloaded (see on github)
This commit is contained in:
Jocelyn Fiat
2011-05-26 17:23:21 +02:00
parent 85cf39f3c6
commit 64cf2b6936
23 changed files with 590 additions and 298 deletions

View File

@@ -2,40 +2,63 @@
GET_REQUEST_HANDLER
inherit
SHARED_DOCUMENT_ROOT
SHARED_URI_CONTENTS_TYPES
HTTP_REQUEST_HANDLER
SHARED_DOCUMENT_ROOT
undefine
default_create
end
SHARED_URI_CONTENTS_TYPES
undefine
default_create
end
HTTP_CONSTANTS
undefine
default_create
end
create
default_create
make
feature
feature {NONE} -- Initialization
make (a_input: like input; a_output: like output)
do
default_create
input := a_input
output := a_output
end
feature -- Access
input: HTTP_INPUT_STREAM
output: HTTP_OUTPUT_STREAM
feature -- Execution
process
-- process the request and create an answer
local
fname: STRING_8
f: RAW_FILE
ctype, extension: STRING_8
ctype, extension: detachable STRING_8
do
create answer.make
if request_uri.is_equal ("/") then
answer.reset
if script_name.is_equal ("/") then
process_default
answer.set_content_type ("text/html")
else
fname := Document_root_cell.item.twin
fname.append (request_uri)
create fname.make_from_string (Document_root)
fname.append (script_name)
debug
print ("URI name: " + fname)
print ("URI filename: " + fname)
end
create f.make (fname)
create answer.make
create f.make (real_filename (fname))
if f.exists then
extension := Ct_table.extension (request_uri)
extension := Ct_table.extension (script_name)
ctype := Ct_table.content_types.item (extension)
if f.is_directory then
process_directory (f)
@@ -58,11 +81,18 @@ feature
answer.set_reply_text ("Not found on this server")
end
end
answer.set_content_length (answer.reply_text.count.out)
if attached answer.reply_text as t then
answer.set_content_length (t.count)
else
answer.set_content_length (0)
end
--| Output the result
output.put_string (answer.reply_header + answer.reply_text)
end
process_default
-- Return a defaul response
-- Return a default response
local
html: STRING_8
do
@@ -118,14 +148,14 @@ feature
html2: STRING_8
htmldir: STRING_8
path: STRING_8
index: INTEGER_32
do
answer.set_reply_text ("")
html1 := " <html> <head> <title> NINO HTTPD </title> " + " </head> " + " <body> " + " <h1> Welcome to NINO HTTPD! </h1> " + " <p> Default page "
html2 := " </p> " + " </body> " + " </html> "
path := f.name.twin
index := path.last_index_of ('/', path.count)
path.remove_substring (1, index)
path := script_name
if path[path.count] = '/' then
path.remove_tail (1)
end
create l_dir.make_open_read (f.name)
files := l_dir.linear_representation
from
@@ -134,7 +164,7 @@ feature
until
files.after
loop
htmldir := htmldir + "<li><a href=%"./" + path + "/" + files.item_for_iteration + "%">" + files.item_for_iteration + "</a> </li>%N"
htmldir := htmldir + "<li><a href=%"" + path + "/" + files.item_for_iteration + "%">" + files.item_for_iteration + "</a> </li>%N"
files.forth
end
htmldir := htmldir + "</ul>"

View File

@@ -20,7 +20,7 @@ inherit
feature
process is
process
-- process the request and create an answer
local
fname: STRING
@@ -57,7 +57,7 @@ feature
end
end
process_default is
process_default
--
local
html : STRING
@@ -76,7 +76,7 @@ feature
end
process_text_file (f: FILE) is
process_text_file (f: FILE)
-- send a text file reply
require
valid_f: f /= Void
@@ -94,7 +94,7 @@ feature
f.close
end
process_raw_file (f: FILE) is
process_raw_file (f: FILE)
-- send a raw file reply
require
valid_f: f /= Void

View File

@@ -1,36 +1,45 @@
deferred class HTTP_REQUEST_HANDLER
feature
set_uri (new_uri: STRING)
-- set new URI
require
valid_uri: new_uri /= Void
do
request_uri := new_uri
inherit
ANY
redefine
default_create
end
feature {NONE} -- Initialization
default_create
do
Precursor
create request_uri.make_empty
create script_name.make_empty
create query_string.make_empty
create answer
create headers.make (0)
end
feature -- Access
request_uri: STRING
-- requested url
set_data (new_data: STRING)
-- set new data
do
data := new_data
end
script_name: STRING
-- Script name
data: STRING
query_string: STRING
-- Query string
data: detachable STRING
-- the entire request message
headers : HASH_TABLE [STRING, STRING]
-- Provides access to the request's HTTP headers, for example:
-- headers["Content-Type"] is "text/plain"
answer: HTTP_RESPONSE
-- reply to this request
set_headers ( a_header : HASH_TABLE [STRING, STRING] )
do
headers := a_header
end
feature -- Execution
process
-- process the request and create an answer
@@ -39,15 +48,68 @@ feature
deferred
end
answer: HTTP_RESPONSE
-- reply to this request
feature -- Recycle
reset
-- reinit the fields
do
request_uri := Void
request_uri.wipe_out
script_name.wipe_out
query_string.wipe_out
data := Void
answer := Void
answer.reset
end
feature -- Element change
set_uri (new_uri: STRING)
-- set new URI
require
valid_uri: new_uri /= Void
local
p: INTEGER
do
request_uri := new_uri
p := new_uri.index_of ('?', 1)
if p > 0 then
script_name := new_uri.substring (1, p - 1)
query_string := new_uri.substring (p + 1, new_uri.count)
else
script_name := new_uri.string
query_string := ""
end
end
set_data (new_data: STRING)
-- set new data
do
data := new_data
end
set_headers ( a_header : HASH_TABLE [STRING, STRING] )
do
headers := a_header
end
feature {NONE} -- Implementation
real_filename (fn: STRING): STRING
-- Real filename from url-path `fn'
--| Find a better design for this piece of code
--| Eventually in a spec/$ISE_PLATFORM/ specific cluster
do
if {PLATFORM}.is_windows then
create Result.make_from_string (fn)
Result.replace_substring_all ("/", "\")
if Result[Result.count] = '\' then
Result.remove_tail (1)
end
else
Result := fn
if Result[Result.count] = '/' then
Result := Result.substring (1, Result.count - 1)
end
end
end
end

View File

@@ -8,108 +8,35 @@ class
POST_REQUEST_HANDLER
inherit
GET_REQUEST_HANDLER
redefine
process
end
SHARED_DOCUMENT_ROOT
create
make
SHARED_URI_CONTENTS_TYPES
feature -- Execution
HTTP_REQUEST_HANDLER
HTTP_CONSTANTS
feature
process is
process
-- process the request and create an answer
local
fname: STRING
f: RAW_FILE
ctype, extension: STRING
l_data: STRING
s: STRING
n: INTEGER
do
fname := document_root_cell.item.twin
fname.append (request_uri)
debug
print ("URI name: " + fname )
end
create f.make (fname)
create answer.make
if f.exists then
extension := ct_table.extension (request_uri)
ctype := ct_table.content_types.item (extension)
-- TODO: This code could be improved to avoid string
-- comparisons
if ctype = Void then
process_default
answer.set_content_type ("text/html")
else
if ctype.is_equal ("text/html") then
process_text_file (f)
else
process_raw_file (f)
end
answer.set_content_type (ctype)
end
else
answer.set_status_code (not_found)
answer.set_reason_phrase (not_found_message)
answer.set_reply_text ("Not found on this server%N%R")
end
end
process_default is
--
local
html : STRING
do
answer.set_reply_text ("")
html := " <html> <head> <title> Micro HTTPD </title> " +
" </head> " +
" <body> " +
" <h1> Welcome to Micro HTTPD! </h1> "+
" <p> Default page " +
" </p> " +
" </body> " +
" </html> "
answer.append_reply_text (html)
end
process_text_file (f: FILE) is
-- send a text file reply
require
valid_f: f /= Void
do
f.open_read
from
answer.set_reply_text ("")
f.read_line
until f.end_of_file
n := 1_024
input.read_stream (n)
s := input.last_string
create l_data.make_empty
until
s.count < n
loop
answer.append_reply_text (f.last_string)
answer.append_reply_text (crlf)
f.read_line
l_data.append_string (s)
input.read_stream (n)
end
f.close
Precursor
end
process_raw_file (f: FILE) is
-- send a raw file reply
require
valid_f: f /= Void
do
-- this is not quite right....
f.open_read
from
answer.set_reply_text ("")
until f.end_of_file
loop
f.read_stream (1024)
answer.append_reply_text (f.last_string)
end
f.close
end
end