Refactor to use the new library structure convention.
21
example/SimpleWebServer/web_server-safe.ecf
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="web_server" uuid="B1D3254D-A58E-4259-9796-8A2843A511A9">
|
||||
<target name="web_server">
|
||||
<root class="APPLICATION" feature="make"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/.git$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" is_attached_by_default="true" void_safety="all">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<setting name="concurrency" value="thread"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="net" location="$ISE_LIBRARY\library\net\net-safe.ecf"/>
|
||||
<library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
|
||||
<library name="nino" location="../../nino-safe.ecf"/>
|
||||
<cluster name="src" location=".\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
@@ -12,10 +12,10 @@
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<setting name="concurrency" value="thread"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="net" location="$ISE_LIBRARY\library\net\net-safe.ecf"/>
|
||||
<library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
|
||||
<library name="nino" location="../nino.ecf"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="net" location="$ISE_LIBRARY\library\net\net.ecf"/>
|
||||
<library name="thread" location="$ISE_LIBRARY\library\thread\thread.ecf"/>
|
||||
<library name="nino" location="../../nino.ecf"/>
|
||||
<cluster name="src" location=".\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
|
Before Width: | Height: | Size: 578 B After Width: | Height: | Size: 578 B |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 703 B After Width: | Height: | Size: 703 B |
|
Before Width: | Height: | Size: 513 B After Width: | Height: | Size: 513 B |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 1009 B After Width: | Height: | Size: 1009 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 921 B After Width: | Height: | Size: 921 B |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 888 B After Width: | Height: | Size: 888 B |
|
Before Width: | Height: | Size: 1004 B After Width: | Height: | Size: 1004 B |
|
Before Width: | Height: | Size: 1014 B After Width: | Height: | Size: 1014 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 884 B After Width: | Height: | Size: 884 B |
|
Before Width: | Height: | Size: 1002 B After Width: | Height: | Size: 1002 B |
|
Before Width: | Height: | Size: 872 B After Width: | Height: | Size: 872 B |
|
Before Width: | Height: | Size: 990 B After Width: | Height: | Size: 990 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 315 B After Width: | Height: | Size: 315 B |
|
Before Width: | Height: | Size: 315 B After Width: | Height: | Size: 315 B |
|
Before Width: | Height: | Size: 315 B After Width: | Height: | Size: 315 B |
|
Before Width: | Height: | Size: 315 B After Width: | Height: | Size: 315 B |
|
Before Width: | Height: | Size: 315 B After Width: | Height: | Size: 315 B |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 733 B After Width: | Height: | Size: 733 B |
|
Before Width: | Height: | Size: 711 B After Width: | Height: | Size: 711 B |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
|
Before Width: | Height: | Size: 608 B After Width: | Height: | Size: 608 B |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 668 B After Width: | Height: | Size: 668 B |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 493 KiB After Width: | Height: | Size: 493 KiB |
|
Before Width: | Height: | Size: 1009 B After Width: | Height: | Size: 1009 B |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
@@ -15,12 +15,7 @@
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="net" location="$ISE_LIBRARY\library\net\net-safe.ecf"/>
|
||||
<library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
|
||||
<cluster name="nino" location=".\src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>head_request_handler.e</exclude>
|
||||
<exclude>shared_http_request_handlers.e</exclude>
|
||||
<exclude>http_protocol_handler.e</exclude>
|
||||
</file_rule>
|
||||
<cluster name="nino" location=".\library\" recursive="true">
|
||||
</cluster>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
7
nino.ecf
@@ -15,12 +15,7 @@
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="net" location="$ISE_LIBRARY\library\net\net.ecf"/>
|
||||
<library name="thread" location="$ISE_LIBRARY\library\thread\thread.ecf"/>
|
||||
<cluster name="nino" location=".\src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>head_request_handler.e</exclude>
|
||||
<exclude>shared_http_request_handlers.e</exclude>
|
||||
<exclude>http_protocol_handler.e</exclude>
|
||||
</file_rule>
|
||||
<cluster name="nino" location=".\library\" recursive="true">
|
||||
</cluster>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
24
readme.txt
@@ -1,21 +1,23 @@
|
||||
Eiffel Nino HTTPD
|
||||
=================
|
||||
The code is based on Xebra and Emu Web Server.
|
||||
|
||||
|
||||
Goal
|
||||
========
|
||||
HTTPD server for development.
|
||||
|
||||
Eiffel Nino is and HTTPD server. It's a work in progress, so maybe it will be refactored.
|
||||
The goal of is to provide a simple web server for development (like Java, Python and Ruby provide)
|
||||
The code is based on Xebra and Emu Web Server.
|
||||
|
||||
|
||||
Goal
|
||||
========
|
||||
HTTPD server for development.
|
||||
|
||||
|
||||
|
||||
Features
|
||||
=======
|
||||
|
||||
=======
|
||||
|
||||
|
||||
|
||||
Testing
|
||||
=======
|
||||
=======
|
||||
The server work fine in Windows and Linux.
|
||||
|
||||
Run the server and point your browser to one of the following URIs
|
||||
@@ -30,7 +32,7 @@ Run the server and point your browser to one of the following URIs
|
||||
8) http://localhost:9000/html5/dataset.html
|
||||
|
||||
Known Issues
|
||||
============
|
||||
============
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,177 +0,0 @@
|
||||
class HTTP_PROTOCOL_HANDLER
|
||||
|
||||
inherit
|
||||
|
||||
SHARED_HTTP_REQUEST_HANDLERS
|
||||
|
||||
HTTP_CONSTANTS
|
||||
|
||||
create
|
||||
make
|
||||
feature -- Initialization
|
||||
|
||||
make (socket: NETWORK_STREAM_SOCKET)
|
||||
require
|
||||
valid_socket: socket /= Void and then socket.is_bound
|
||||
local
|
||||
done: BOOLEAN
|
||||
client_socket: detachable NETWORK_STREAM_SOCKET
|
||||
do
|
||||
from
|
||||
done := False
|
||||
until
|
||||
done
|
||||
loop
|
||||
socket.accept
|
||||
client_socket := socket.accepted
|
||||
if client_socket = Void then
|
||||
-- Some error occured, perhaps because of the timeout
|
||||
-- We probably should provide some diagnostics here
|
||||
io.put_string ("accept result = Void")
|
||||
io.put_new_line
|
||||
else
|
||||
perform_client_communication (client_socket)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
feature -- Access
|
||||
method : STRING
|
||||
uri : STRING
|
||||
version : STRING
|
||||
request_header_map : HASH_TABLE [STRING,STRING]
|
||||
-- Containts key value of the header
|
||||
|
||||
feature -- Implementation
|
||||
|
||||
perform_client_communication (socket: NETWORK_STREAM_SOCKET)
|
||||
require
|
||||
socket_attached: socket /= Void
|
||||
socket_valid: socket.is_open_read and then socket.is_open_write
|
||||
local
|
||||
done: BOOLEAN
|
||||
l_address, l_peer_address: detachable NETWORK_SOCKET_ADDRESS
|
||||
do
|
||||
l_address := socket.address
|
||||
l_peer_address := socket.peer_address
|
||||
check
|
||||
l_address_attached: l_address /= Void
|
||||
l_peer_address_attached: l_peer_address /= Void
|
||||
end
|
||||
io.put_string ("Accepted client on the listen socket address = "+ l_address.host_address.host_address + " port = " + l_address.port.out +".")
|
||||
io.put_new_line
|
||||
io.put_string ("%T Accepted client address = " + l_peer_address.host_address.host_address + " , port = " + l_peer_address.port.out)
|
||||
io.put_new_line
|
||||
create request_header_map.make (20)
|
||||
from
|
||||
done := False
|
||||
until
|
||||
done
|
||||
loop
|
||||
if socket.socket_ok then
|
||||
done := receive_message_and_send_reply (socket)
|
||||
request_header_map.wipe_out
|
||||
else
|
||||
done := True
|
||||
end
|
||||
end
|
||||
io.put_string ("Finished processing the client, address = "+ l_peer_address.host_address.host_address + " port = " + l_peer_address.port.out + ".")
|
||||
io.put_new_line
|
||||
end
|
||||
|
||||
receive_message_and_send_reply (client_socket: NETWORK_STREAM_SOCKET): BOOLEAN
|
||||
require
|
||||
socket_attached: client_socket /= Void
|
||||
socket_valid: client_socket.is_open_read and then client_socket.is_open_write
|
||||
local
|
||||
message: detachable STRING
|
||||
l_http_request : HTTP_REQUEST_HANDLER
|
||||
do
|
||||
parse_request_line (client_socket)
|
||||
message := receive_message_internal (client_socket)
|
||||
if method.is_equal (Get) then
|
||||
create {GET_REQUEST_HANDLER} l_http_request
|
||||
l_http_request.set_uri (uri)
|
||||
l_http_request.process
|
||||
send_message (client_socket, l_http_request.answer.reply_header + l_http_request.answer.reply_text)
|
||||
elseif method.is_equal (Post) then
|
||||
elseif method.is_equal (Put) then
|
||||
elseif method.is_equal (Options) then
|
||||
elseif method.is_equal (Head) then
|
||||
elseif method.is_equal (Delete) then
|
||||
elseif method.is_equal (Trace) then
|
||||
elseif method.is_equal (Connect) then
|
||||
else
|
||||
debug
|
||||
print ("Method not supported")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
parse_request_line (socket: NETWORK_STREAM_SOCKET)
|
||||
require
|
||||
socket: socket /= Void and then not socket.is_closed
|
||||
do
|
||||
socket.read_line
|
||||
parse_request_line_internal (socket.last_string)
|
||||
end
|
||||
|
||||
receive_message_internal (socket: NETWORK_STREAM_SOCKET) : STRING
|
||||
require
|
||||
socket: socket /= Void and then not socket.is_closed
|
||||
local
|
||||
end_of_stream : BOOLEAN
|
||||
pos : INTEGER
|
||||
line : STRING
|
||||
do
|
||||
from
|
||||
socket.read_line
|
||||
Result := ""
|
||||
until
|
||||
end_of_stream
|
||||
loop
|
||||
line := socket.last_string
|
||||
print ("%N" +line+ "%N")
|
||||
pos := line.index_of(':',1)
|
||||
request_header_map.put (line.substring (pos + 1, line.count), line.substring (1,pos-1))
|
||||
Result.append(socket.last_string)
|
||||
if not socket.last_string.is_equal("%R") and socket.socket_ok then
|
||||
socket.read_line
|
||||
else
|
||||
end_of_stream := True
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
send_message (client_socket : NETWORK_STREAM_SOCKET ; a_msg: STRING)
|
||||
local
|
||||
a_package : PACKET
|
||||
a_data : MANAGED_POINTER
|
||||
c_string : C_STRING
|
||||
do
|
||||
create c_string.make (a_msg)
|
||||
create a_data.make_from_pointer (c_string.item, a_msg.count + 1)
|
||||
create a_package.make_from_managed_pointer (a_data)
|
||||
client_socket.send (a_package, 0)
|
||||
end
|
||||
|
||||
|
||||
parse_request_line_internal (line: STRING)
|
||||
require
|
||||
line /= Void
|
||||
local
|
||||
pos, next_pos: INTEGER
|
||||
do
|
||||
print ("%N parse request line:%N" + line)
|
||||
pos := line.index_of (' ', 1)
|
||||
method := line.substring (1, pos - 1)
|
||||
next_pos := line.index_of (' ', pos+1)
|
||||
uri := line.substring (pos+1, next_pos-1)
|
||||
version := line.substring (next_pos + 1, line.count)
|
||||
ensure
|
||||
not_void_method: method /= Void
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,13 +0,0 @@
|
||||
class SHARED_HTTP_REQUEST_HANDLERS
|
||||
|
||||
feature
|
||||
|
||||
http_request_handlers: HASH_TABLE [HTTP_REQUEST_HANDLER, STRING]
|
||||
local
|
||||
a_handler: HTTP_REQUEST_HANDLER
|
||||
once
|
||||
create Result.make (5)
|
||||
create {GET_REQUEST_HANDLER} a_handler
|
||||
Result.put (a_handler, "GET")
|
||||
end
|
||||
end
|
||||