diff --git a/README b/README deleted file mode 100644 index e69de29b..00000000 diff --git a/application.e b/application.e deleted file mode 100644 index ab05454b..00000000 --- a/application.e +++ /dev/null @@ -1,26 +0,0 @@ -note - description : "nino application root class" - date : "$Date$" - revision : "$Revision$" - -class - APPLICATION - -inherit - ARGUMENTS - -create - make - -feature {NONE} -- Initialization - - make - -- Run application. - local - l_server : HTTP_SERVER - do - create l_server.make - l_server.setup - end - -end diff --git a/exception_trace.log b/exception_trace.log deleted file mode 100644 index e44d7f4e..00000000 --- a/exception_trace.log +++ /dev/null @@ -1,47 +0,0 @@ - -nino: system execution failed. -Following is the set of recorded exceptions: - -******************************** Thread exception ***************************** -In thread Child thread 0x88 (thread id) -******************************************************************************* -------------------------------------------------------------------------------- -Class / Object Routine Nature of exception Effect -------------------------------------------------------------------------------- -TCP_STREAM_SOCKET send @1 socket_exists: -<00000000024B1A48> (From SOCKET) Precondition violated. Fail -------------------------------------------------------------------------------- -GET_REQUEST_HANDLER send_message @4 -<00000000024B4428> Routine failure. Fail -------------------------------------------------------------------------------- -GET_REQUEST_HANDLER execute @2 -<00000000024B4428> Routine failure. Fail -------------------------------------------------------------------------------- -GET_REQUEST_HANDLER thr_main @4 -<00000000024B4428> (From THREAD) Routine failure. Rescue -------------------------------------------------------------------------------- -APPLICATION root's creation -<00000000024B05A8> Routine failure. Exit -------------------------------------------------------------------------------- - -nino: system execution failed. -Following is the set of recorded exceptions: - -******************************** Thread exception ***************************** -In thread Child thread 0x88 (thread id) -******************************************************************************* -------------------------------------------------------------------------------- -Class / Object Routine Nature of exception Effect -------------------------------------------------------------------------------- -TCP_STREAM_SOCKET put_string @1 extendible: -<0000000002621A48> (From SOCKET) Precondition violated. Fail -------------------------------------------------------------------------------- -GET_REQUEST_HANDLER execute @2 -<0000000002624408> Routine failure. Fail -------------------------------------------------------------------------------- -GET_REQUEST_HANDLER thr_main @4 -<0000000002624408> (From THREAD) Routine failure. Rescue -------------------------------------------------------------------------------- -APPLICATION root's creation -<00000000026205A8> Routine failure. Exit -------------------------------------------------------------------------------- diff --git a/http_connection_handler.e b/http_connection_handler.e deleted file mode 100644 index 455f6631..00000000 --- a/http_connection_handler.e +++ /dev/null @@ -1,274 +0,0 @@ -note - description: "Summary description for {HTTP_CONNECTION_HANDLER}." - author: "" - date: "$Date$" - revision: "$Revision$" - -class - HTTP_CONNECTION_HANDLER - -inherit - - THREAD - HTTP_CONSTANTS -create - make - -feature {NONE} -- Initialization - - make (a_main_server: like main_server; a_name: STRING) - -- Creates a {HTTP_CONNECTION_HANDLER}, assigns the main_server and sets the current_request_message to empty. - -- - -- `a_main_server': The main server object - -- `a_name': The name of this module - require - a_main_server_attached: a_main_server /= Void - a_name_attached: a_name /= Void - do - main_server := a_main_server - create current_request_message.make_empty - create method.make_empty - create uri.make_empty - create request_header_map.make (10) - is_stop_requested := False - ensure - main_server_set: a_main_server ~ main_server - current_request_message_attached: current_request_message /= Void - end - -feature -- Inherited Features - - execute - -- - -- Creates a socket and connects to the http server. - local - l_http_socket: detachable TCP_STREAM_SOCKET - do - is_stop_requested := False - create l_http_socket.make_server_by_port ({HTTP_CONSTANTS}.Http_server_port) - if not l_http_socket.is_bound then - print ("Socket could not be bound on port " + {HTTP_CONSTANTS}.Http_server_port.out ) - else - from - l_http_socket.listen ({HTTP_CONSTANTS}.Max_tcp_clients) - print ("%NHTTP Connection Server ready on port " + {HTTP_CONSTANTS}.Http_server_port.out +"%N") - until - is_stop_requested - loop - l_http_socket.accept - if not is_stop_requested then - if attached l_http_socket.accepted as l_thread_http_socket then - receive_message_and_send_replay (l_thread_http_socket) - l_thread_http_socket.cleanup - check - socket_closed: l_thread_http_socket.is_closed - end - end - end - end - l_http_socket.cleanup - check - socket_is_closed: l_http_socket.is_closed - end - end - print ("HTTP Connection Server ends.") - rescue - print ("HTTP Connection Server shutdown due to exception. Please relaunch manually.") - - if attached l_http_socket as ll_http_socket then - ll_http_socket.cleanup - check - socket_is_closed: ll_http_socket.is_closed - end - end - is_stop_requested := True - retry - end - -feature -- Access - - is_stop_requested: BOOLEAN - -- Set true to stop accept loop - - -feature {NONE} -- Access - - request_header_map : HASH_TABLE [STRING,STRING] - -- Containts key value of the header - - main_server: HTTP_SERVER - -- The main server object - - current_request_message: STRING - -- Stores the current request message received from http server - - Max_fragments: INTEGER = 1000 - -- Defines the maximum number of fragments that can be received - - method : STRING - -- http verb - - uri : STRING - -- http endpoint - - version : STRING - -- http_version -feature -- Status setting - - shutdown - -- Stops the thread - do - is_stop_requested := True - end - -feature {NONE} -- Implementation - - - - read_string_from_socket (a_socket: TCP_STREAM_SOCKET; a_n: NATURAL): STRING - -- Reads characters from the socket and concatenates them to a string - -- - -- `a_socket': The socket to read from - -- `a_n': The number of characters to read - -- `Result': The created string - require - socket_is_open: not a_socket.is_closed - local - l_read_size: INTEGER - l_buf: detachable STRING - do - create Result.make (a_n.as_integer_32) - from - l_read_size := 0 - Result := "" - l_buf := "" - until - l_buf.is_equal ("%R") - loop - a_socket.read_line_thread_aware - l_buf := a_socket.last_string - if l_buf /= Void then - Result.append (l_buf) - end - if l_buf.is_equal ("%R") then - a_socket.set_nodelay - a_socket.put_string ("HTTP/1.1 100 Continue%/13/%/10/%/13/%/10/") - a_socket.close_socket - end - - l_read_size := Result.count - end - ensure - Result_attached: Result /= Void - end - - - -feature -- New implementation - - - parse_http_request_line (line: STRING) - require - line /= Void - local - pos, next_pos: INTEGER - do - print ("%N parse http request line:%N" + line) - -- parse (this should be done by a lexer) - 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) - ensure - not_void_method: method /= Void - end - -feature -- New Implementation - receive_message_and_send_replay (client_socket: TCP_STREAM_SOCKET) - require - socket_attached: client_socket /= Void --- socket_valid: client_socket.is_open_read and then client_socket.is_open_write - a_http_socket:client_socket /= Void and then not client_socket.is_closed - 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 --- client_socket.send_message (l_http_request.answer.reply_header + l_http_request.answer.reply_text) - client_socket.put_string (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: TCP_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_thread_aware - 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_thread_aware - else - end_of_stream := True - end - end - 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 - -invariant - main_server_attached: main_server /= Void - current_request_message_attached: current_request_message /= Void - -end diff --git a/http_server.e b/http_server.e deleted file mode 100644 index e6e73edf..00000000 --- a/http_server.e +++ /dev/null @@ -1,56 +0,0 @@ -note - description: "Summary description for {HTTP_SERVER}." - author: "" - date: "$Date$" - revision: "$Revision$" - -class - HTTP_SERVER -inherit - SHARED_DOCUMENT_ROOT -create - make -feature -- Initialization - make - do - - end - - setup - local - l_http_handler : HTTP_CONNECTION_HANDLER - do - print("%N%N%N") - print ("Starting Web Application Server:%N") - stop := False - document_root_cell.put (document_root) - create l_http_handler.make (current,"HTTP_HANDLER") - l_http_handler.launch - run - end - - shutdown_server - do - stop := True - end - -feature -- Access - stop: BOOLEAN - -- Stops the server - - document_root: STRING = "./webroot" - -feature {NONE} -- implementation - - run - -- Start the server - local - l_thread: EXECUTION_ENVIRONMENT - do - create l_thread - from until stop loop - l_thread.sleep (1000000) - end - - end -end diff --git a/nino.ecf b/nino.ecf index 5170547d..992aff1d 100644 --- a/nino.ecf +++ b/nino.ecf @@ -1,19 +1,25 @@ - + - - diff --git a/request/http_request_handler.e b/request/http_request_handler.e deleted file mode 100644 index 6d174a9f..00000000 --- a/request/http_request_handler.e +++ /dev/null @@ -1,53 +0,0 @@ -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 - end - - request_uri: STRING - -- requested url - - set_data (new_data: STRING) - -- set new data - do - data := new_data - end - - data: 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" - - - set_headers ( a_header : HASH_TABLE [STRING, STRING] ) - do - headers := a_header - end - - process - -- process the request and create an answer - require - valid_uri: request_uri /= Void - deferred - end - - answer: HTTP_RESPONSE - -- reply to this request - - reset - -- reinit the fields - do - request_uri := Void - data := Void - answer := Void - end - -end diff --git a/request/post_request_handler.e b/request/post_request_handler.e deleted file mode 100644 index 3658d28f..00000000 --- a/request/post_request_handler.e +++ /dev/null @@ -1,115 +0,0 @@ -note - description: "Summary description for {POST_REQUEST_HANDLER}." - author: "" - date: "$Date$" - revision: "$Revision$" - -class - POST_REQUEST_HANDLER - -inherit - - SHARED_DOCUMENT_ROOT - - SHARED_URI_CONTENTS_TYPES - - HTTP_REQUEST_HANDLER - - HTTP_CONSTANTS - -feature - - - process is - -- process the request and create an answer - local - fname: STRING - f: RAW_FILE - ctype, extension: STRING - 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 := " Micro HTTPD " + - " " + - " " + - "

Welcome to Micro HTTPD!

"+ - "

Default page " + - - "

" + - " " + - " " - 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 - loop - answer.append_reply_text (f.last_string) - answer.append_reply_text (crlf) - f.read_line - end - f.close - 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 diff --git a/shared_document_root.e b/shared_document_root.e deleted file mode 100644 index 6b17bb59..00000000 --- a/shared_document_root.e +++ /dev/null @@ -1,16 +0,0 @@ -note - description: "Summary description for {SHARED_DOCUMENT_ROOT}." - author: "" - date: "$Date$" - revision: "$Revision$" - -class - SHARED_DOCUMENT_ROOT -feature - - document_root_cell: CELL [STRING] - once ("PROCESS") - create Result.put (Void) - end - -end diff --git a/src/README b/src/README new file mode 100644 index 00000000..d84f5358 --- /dev/null +++ b/src/README @@ -0,0 +1,5 @@ +Eiffel Web 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) + + + diff --git a/src/configuration/http_server_configuration.e b/src/configuration/http_server_configuration.e new file mode 100644 index 00000000..e7547db2 --- /dev/null +++ b/src/configuration/http_server_configuration.e @@ -0,0 +1,68 @@ +note + description: "Summary description for {HTTP_SERVER_CONFIGURATION}." + date: "$Date$" + revision: "$Revision$" + +class + HTTP_SERVER_CONFIGURATION + +create + make + +feature {NONE} -- Initialization + + make + do + http_server_port := 80 + max_tcp_clients := 100 + socket_accept_timeout := 1_000 + socket_connect_timeout := 5_000 + document_root := "htdocs" + force_single_threaded := False + end + +feature -- Access + + Server_details : STRING = "Server : NANO Eiffel Server" + + document_root: STRING assign set_document_root + http_server_port: INTEGER assign set_http_server_port + max_tcp_clients: INTEGER assign set_max_tcp_clients + socket_accept_timeout: INTEGER assign set_socket_accept_timeout + socket_connect_timeout: INTEGER assign set_socket_connect_timeout + force_single_threaded: BOOLEAN assign set_force_single_threaded + +feature -- Element change + + set_http_server_port (v: like http_server_port) + do + http_server_port := v + end + + set_document_root (v: like document_root) + do + document_root := v + end + + set_max_tcp_clients (v: like max_tcp_clients) + do + max_tcp_clients := v + end + + set_socket_accept_timeout (v: like socket_accept_timeout) + do + socket_accept_timeout := v + end + + set_socket_connect_timeout (v: like socket_connect_timeout) + do + socket_connect_timeout := v + end + + set_force_single_threaded (v: like force_single_threaded) + do + force_single_threaded := v + end + + +end diff --git a/src/configuration/http_server_shared_configuration.e b/src/configuration/http_server_shared_configuration.e new file mode 100644 index 00000000..e5cc62ec --- /dev/null +++ b/src/configuration/http_server_shared_configuration.e @@ -0,0 +1,45 @@ +note + description: "Summary description for {HTTP_SERVER_SHARED_CONFIGURATION}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + HTTP_SERVER_SHARED_CONFIGURATION + +feature -- Access + + server_configuration: detachable HTTP_SERVER_CONFIGURATION + -- Shared configuration + do + if attached server_configuration_cell.item as l_cfg then + Result := l_cfg + end + end + + document_root: STRING_8 + -- Shared document root + do + if attached server_configuration as l_cfg then + Result := l_cfg.document_root + else + Result := "" + end + end + +feature -- Element change + + set_server_configuration (a_cfg: like server_configuration) + -- Set `server_configuration' to `a_cfg'. + do + server_configuration_cell.replace (a_cfg) + end + +feature {NONE} -- Implementation + + server_configuration_cell: CELL [detachable HTTP_SERVER_CONFIGURATION] + once ("PROCESS") + create Result.put (Void) + end + +end diff --git a/src/http_connection_handler.e b/src/http_connection_handler.e new file mode 100644 index 00000000..48872289 --- /dev/null +++ b/src/http_connection_handler.e @@ -0,0 +1,175 @@ +note + description: "Summary description for {HTTP_CONNECTION_HANDLER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + HTTP_CONNECTION_HANDLER + +inherit + HTTP_HANDLER + redefine + make + end + +feature {NONE} -- Initialization + + make (a_main_server: like main_server; a_name: STRING) + -- Creates a {HTTP_CONNECTION_HANDLER}, assigns the main_server and sets the current_request_message to empty. + -- + -- `a_main_server': The main server object + -- `a_name': The name of this module + do + Precursor (a_main_server, a_name) + reset + end + + reset + do + create method.make_empty + create uri.make_empty + create request_header.make_empty + create request_header_map.make (10) + remote_info := Void + end + +feature -- Execution + + receive_message_and_send_reply (client_socket: TCP_STREAM_SOCKET) + local + l_input: HTTP_INPUT_STREAM + l_output: HTTP_OUTPUT_STREAM + l_remote_info: detachable like remote_info + do + create l_input.make (client_socket) + create l_output.make (client_socket) + + + create l_remote_info + if attached client_socket.address as l_addr then + l_remote_info.addr := l_addr.host_address.host_address + l_remote_info.hostname := l_addr.host_address.host_name + l_remote_info.port := l_addr.port + end + + analyze_request_message (l_input) + process_request (Current, l_input, l_output) + reset + end + +feature -- Request processing + + process_request (a_handler: HTTP_CONNECTION_HANDLER; a_input: HTTP_INPUT_STREAM; a_output: HTTP_OUTPUT_STREAM) + -- Process request ... + require + a_handler_attached: a_handler /= Void + a_uri_attached: a_handler.uri /= Void + a_method_attached: a_handler.method /= Void + a_header_map_attached: a_handler.request_header_map /= Void + a_header_text_attached: a_handler.request_header /= Void + a_input_attached: a_input /= Void + a_output_attached: a_output /= Void + deferred + end + +feature -- Access + + request_header: STRING + -- Header' source + + request_header_map : HASH_TABLE [STRING,STRING] + -- Contains key:value of the header + + method: STRING + -- http verb + + uri: STRING + -- http endpoint + + version: detachable STRING + -- http_version + --| unused for now + + remote_info: detachable TUPLE [addr: STRING; hostname: STRING; port: INTEGER] + +feature -- Parsing + + parse_http_request_line (line: STRING) + require + line /= Void + local + pos, next_pos: INTEGER + do + print ("%N parse http request line:%N" + line) + -- parse (this should be done by a lexer) + 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) + ensure + not_void_method: method /= Void + end + + + analyze_request_message (a_input: HTTP_INPUT_STREAM) + require + input_readable: a_input /= Void and then a_input.is_readable + local + end_of_stream : BOOLEAN + pos : INTEGER + line : STRING + val: STRING + txt: STRING + do + create txt.make (64) + a_input.read_line + line := a_input.last_string + analyze_request_line (line) + txt.append (line) + txt.append_character ('%N') + + request_header := txt + from + a_input.read_line + until + end_of_stream + loop + line := a_input.last_string + print ("%N" +line+ "%N") + pos := line.index_of (':',1) + val := line.substring (pos + 1, line.count) + if val[val.count] = '%R' then + val.remove_tail (1) + end + request_header_map.put (val, line.substring (1,pos-1)) + txt.append (line) + txt.append_character ('%N') + if line.is_empty or else line[1] = '%R' then + end_of_stream := True + else + a_input.read_line + end + end + end + + analyze_request_line (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 + +invariant + request_header_attached: request_header /= Void + +end diff --git a/http_constants.e b/src/http_constants.e similarity index 92% rename from http_constants.e rename to src/http_constants.e index b263b76b..791ba309 100644 --- a/http_constants.e +++ b/src/http_constants.e @@ -81,13 +81,6 @@ feature -- content types text_html: STRING = "text/html" -feature -- Network - Server_datails : STRING = "Server : NANO Eiffel Server" - Http_server_port: INTEGER = 9000 - Max_tcp_clients: INTEGER = 100 - Socket_accept_timeout: INTEGER = 1000 - Socket_connect_timeout: INTEGER = 5000 - feature -- General Header Fields -- There are a few header fields which have general applicability for both request and response messages, diff --git a/http_encoding_facilities.e b/src/http_encoding_facilities.e similarity index 100% rename from http_encoding_facilities.e rename to src/http_encoding_facilities.e diff --git a/src/http_handler.e b/src/http_handler.e new file mode 100644 index 00000000..80369127 --- /dev/null +++ b/src/http_handler.e @@ -0,0 +1,123 @@ +note + description: "Summary description for {HTTP_CONNECTION_HANDLER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + HTTP_HANDLER + +inherit + THREAD + + HTTP_CONSTANTS + +feature {NONE} -- Initialization + + make (a_main_server: like main_server; a_name: STRING) + -- Creates a {HTTP_HANDLER}, assigns the main_server and initialize various values + -- + -- `a_main_server': The main server object + -- `a_name': The name of this module + require + a_main_server_attached: a_main_server /= Void + a_name_attached: a_name /= Void + do + main_server := a_main_server + is_stop_requested := False + ensure + main_server_set: a_main_server ~ main_server + end + +feature -- Inherited Features + + execute + -- + -- Creates a socket and connects to the http server. + local + l_http_socket: detachable TCP_STREAM_SOCKET + l_http_port: INTEGER + do + is_stop_requested := False + l_http_port := main_server_configuration.http_server_port + create l_http_socket.make_server_by_port (l_http_port) + if not l_http_socket.is_bound then + print ("Socket could not be bound on port " + l_http_port.out ) + else + from + l_http_socket.listen (main_server_configuration.max_tcp_clients) + print ("%NHTTP Connection Server ready on port " + l_http_port.out +"%N") + until + is_stop_requested + loop + l_http_socket.accept + if not is_stop_requested then + if attached l_http_socket.accepted as l_thread_http_socket then + receive_message_and_send_reply (l_thread_http_socket) + l_thread_http_socket.cleanup + check + socket_closed: l_thread_http_socket.is_closed + end + end + end + end + l_http_socket.cleanup + check + socket_is_closed: l_http_socket.is_closed + end + end + print ("HTTP Connection Server ends.") + rescue + print ("HTTP Connection Server shutdown due to exception. Please relaunch manually.") + + if attached l_http_socket as ll_http_socket then + ll_http_socket.cleanup + check + socket_is_closed: ll_http_socket.is_closed + end + end + is_stop_requested := True + retry + end + +feature -- Access + + is_stop_requested: BOOLEAN + -- Set true to stop accept loop + +feature {NONE} -- Access + + main_server: HTTP_SERVER + -- The main server object + + main_server_configuration: HTTP_SERVER_CONFIGURATION + -- The main server's configuration + do + Result := main_server.configuration + end + + Max_fragments: INTEGER = 1000 + -- Defines the maximum number of fragments that can be received + +feature -- Status setting + + shutdown + -- Stops the thread + do + is_stop_requested := True + end + +feature -- Execution + + receive_message_and_send_reply (client_socket: TCP_STREAM_SOCKET) + require + socket_attached: client_socket /= Void +-- socket_valid: client_socket.is_open_read and then client_socket.is_open_write + a_http_socket:client_socket /= Void and then not client_socket.is_closed + deferred + end + +invariant + main_server_attached: main_server /= Void + +end diff --git a/http_protocol_handler.e b/src/http_protocol_handler.e similarity index 94% rename from http_protocol_handler.e rename to src/http_protocol_handler.e index bb1995dd..6be59b67 100644 --- a/http_protocol_handler.e +++ b/src/http_protocol_handler.e @@ -70,7 +70,7 @@ feature -- Implementation done loop if socket.socket_ok then - done := receive_message_and_send_replay (socket) + done := receive_message_and_send_reply (socket) request_header_map.wipe_out else done := True @@ -80,7 +80,7 @@ feature -- Implementation io.put_new_line end - receive_message_and_send_replay (client_socket: NETWORK_STREAM_SOCKET): BOOLEAN + 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 diff --git a/src/http_server.e b/src/http_server.e new file mode 100644 index 00000000..0bfe0186 --- /dev/null +++ b/src/http_server.e @@ -0,0 +1,65 @@ +note + description: "Summary description for {HTTP_SERVER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + HTTP_SERVER + +inherit + HTTP_SERVER_SHARED_CONFIGURATION + +create + make + +feature -- Initialization + + make (cfg: like configuration) + do + configuration := cfg + end + + setup (a_http_handler : HTTP_HANDLER) + require + a_http_handler_valid: a_http_handler /= Void + do + print("%N%N%N") + print ("Starting Web Application Server (port="+ configuration.http_server_port.out +"):%N") + stop_requested := False + set_server_configuration (configuration) + if configuration.force_single_threaded then + a_http_handler.execute + else + a_http_handler.launch + a_http_handler.join + end + end + + shutdown_server + do + stop_requested := True + end + +feature -- Access + + configuration: HTTP_SERVER_CONFIGURATION + -- Configuration of the server + + stop_requested: BOOLEAN + -- Stops the server + +feature {NONE} -- implementation + + run + -- Start the server + local + e: EXECUTION_ENVIRONMENT + do + create e + from until stop_requested loop + e.sleep (1_000_000) + end + end + +end diff --git a/src/io/http_input_stream.e b/src/io/http_input_stream.e new file mode 100644 index 00000000..9dc67f73 --- /dev/null +++ b/src/io/http_input_stream.e @@ -0,0 +1,64 @@ +note + description: "Summary description for {HTTP_INPUT_STREAM}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + HTTP_INPUT_STREAM + +create + make + +feature {NONE} -- Initialization + + make (a_socket: like source) + do + source := a_socket + create last_string.make_empty + end + + source: TCP_STREAM_SOCKET + +feature -- Status Report + + is_readable: BOOLEAN + -- Is readable? + do + Result := source.is_open_read + end + +feature -- Basic operation + + read_line + require + is_readable: is_readable + do + last_string.wipe_out + if source.socket_ok then + source.read_line_thread_aware + last_string.append_string (source.last_string) + end + end + + read_stream (nb_char: INTEGER) + -- Read a string of at most `nb_char' bound characters + -- or until end of file. + -- Make result available in `last_string'. + require + nb_char_positive: nb_char > 0 + is_readable: is_readable + do + last_string.wipe_out + if source.socket_ok then + source.read_stream_thread_aware (nb_char) + last_string.append_string (source.last_string) + end + end + +feature -- Access + + last_string: STRING + -- Last string read + +end diff --git a/src/io/http_output_stream.e b/src/io/http_output_stream.e new file mode 100644 index 00000000..a3d37a6f --- /dev/null +++ b/src/io/http_output_stream.e @@ -0,0 +1,31 @@ +note + description: "Summary description for {HTTP_OUTPUT_STREAM}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + HTTP_OUTPUT_STREAM + +create + make + +feature {NONE} -- Initialization + + make (a_socket: like target) + do + target := a_socket + end + + target: TCP_STREAM_SOCKET + +feature -- Basic operation + + put_string (s: STRING) + -- Write string `s' to `target' + do + target.put_string (s) + end + + +end diff --git a/request/get_request_handler.e b/src/request/get_request_handler.e similarity index 69% rename from request/get_request_handler.e rename to src/request/get_request_handler.e index bf1b1f2d..e37d77b2 100644 --- a/request/get_request_handler.e +++ b/src/request/get_request_handler.e @@ -2,40 +2,63 @@ GET_REQUEST_HANDLER inherit - SHARED_DOCUMENT_ROOT - - SHARED_URI_CONTENTS_TYPES - HTTP_REQUEST_HANDLER + HTTP_SERVER_SHARED_CONFIGURATION + 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 := " NINO HTTPD " + " " + " " + "

Welcome to NINO HTTPD!

" + "

Default page " html2 := "

" + " " + " " - 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 + "
  • " + files.item_for_iteration + "
  • %N" + htmldir := htmldir + "
  • " + files.item_for_iteration + "
  • %N" files.forth end htmldir := htmldir + "" diff --git a/request/head_request_handler.e b/src/request/head_request_handler.e similarity index 90% rename from request/head_request_handler.e rename to src/request/head_request_handler.e index 748b9799..bf0cdd54 100644 --- a/request/head_request_handler.e +++ b/src/request/head_request_handler.e @@ -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 diff --git a/src/request/http_request_handler.e b/src/request/http_request_handler.e new file mode 100644 index 00000000..0043ff0d --- /dev/null +++ b/src/request/http_request_handler.e @@ -0,0 +1,115 @@ +deferred class HTTP_REQUEST_HANDLER + +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 + + script_name: STRING + -- Script name + + 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 + +feature -- Execution + + process + -- process the request and create an answer + require + valid_uri: request_uri /= Void + deferred + end + +feature -- Recycle + + reset + -- reinit the fields + do + request_uri.wipe_out + script_name.wipe_out + query_string.wipe_out + data := 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 diff --git a/src/request/post_request_handler.e b/src/request/post_request_handler.e new file mode 100644 index 00000000..0dadf245 --- /dev/null +++ b/src/request/post_request_handler.e @@ -0,0 +1,42 @@ +note + description: "Summary description for {POST_REQUEST_HANDLER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + POST_REQUEST_HANDLER + +inherit + GET_REQUEST_HANDLER + redefine + process + end + +create + make + +feature -- Execution + + process + -- process the request and create an answer + local + l_data: STRING + s: STRING + n: INTEGER + do + from + n := 1_024 + input.read_stream (n) + s := input.last_string + create l_data.make_empty + until + s.count < n + loop + l_data.append_string (s) + input.read_stream (n) + end + Precursor + end + +end diff --git a/response/http_response.e b/src/response/http_response.e similarity index 68% rename from response/http_response.e rename to src/response/http_response.e index 0faf6456..0c4b0d8e 100644 --- a/response/http_response.e +++ b/src/response/http_response.e @@ -2,12 +2,38 @@ class HTTP_RESPONSE inherit - HTTP_CONSTANTS + redefine + default_create + end create + default_create - make +feature -- creation + + default_create + do + Precursor + set_defaults + end + + set_defaults + -- Set default values for the reply + do + status_code := ok + create content_length_data.make_empty + reason_phrase := ok_message + content_type_data := text_html + set_reply_text (Void) + end + +feature -- Recycle + + reset + do + set_defaults + end feature -- response header fields @@ -17,11 +43,19 @@ feature -- response header fields content_length_data : STRING -- length - set_content_length (new_content_length: STRING) + reason_phrase: STRING + -- message, if any + + content_type_data: STRING + -- type of content in this reply (eg. text/html) + +feature -- Element change + + set_content_length (new_content_length: INTEGER) require - not_void: new_content_length /= Void + positive_or_zero: new_content_length >= 0 do - content_length_data := new_content_length + content_length_data := new_content_length.out end set_status_code (new_status_code: STRING) @@ -31,9 +65,6 @@ feature -- response header fields status_code := new_status_code end - reason_phrase: STRING - -- message, if any - set_reason_phrase (new_reason_phrase: STRING) require not_void: new_reason_phrase /= Void @@ -41,9 +72,6 @@ feature -- response header fields reason_phrase := new_reason_phrase end - content_type_data: STRING - -- type of content in this reply (eg. text/html) - set_content_type (new_content_type: STRING) require not_void: new_content_type /= Void @@ -51,18 +79,7 @@ feature -- response header fields content_type_data := new_content_type end -feature -- creation - - make - do - -- set default values for the reply - status_code := ok - reason_phrase := ok_message - content_type_data := text_html - end - -feature -- access these to send a reply - +feature -- Access: send reply reply_header: STRING -- header @@ -73,7 +90,7 @@ feature -- access these to send a reply Result.extend (' ') Result.append (reason_phrase) Result.append (crlf) - Result.append (Server_datails) + Result.append ({HTTP_SERVER_CONFIGURATION}.Server_details) Result.append (crlf) Result.append (Content_type + ": ") Result.append (content_type_data) @@ -89,7 +106,7 @@ feature -- access these to send a reply reply_header_continue: STRING -- header do - Result :=http_version_1_1.twin + Result := http_version_1_1.twin Result.extend (' ') Result.append (status_code) Result.extend (' ') @@ -100,14 +117,19 @@ feature -- access these to send a reply -- then keep the connection alive end - reply_text: STRING -- reply text - set_reply_text (new_text: STRING) +feature -- Change element: send reply + + set_reply_text (new_text: detachable STRING) -- text could be Void do - reply_text := new_text + if new_text = Void then + create reply_text.make_empty + else + reply_text := new_text + end end append_reply_text (more_text: STRING) diff --git a/shared_http_request_handlers.e b/src/shared_http_request_handlers.e similarity index 93% rename from shared_http_request_handlers.e rename to src/shared_http_request_handlers.e index 8cee2ca1..851d012c 100644 --- a/shared_http_request_handlers.e +++ b/src/shared_http_request_handlers.e @@ -2,7 +2,7 @@ class SHARED_HTTP_REQUEST_HANDLERS feature - http_request_handlers: HASH_TABLE [HTTP_REQUEST_HANDLER, STRING] is + http_request_handlers: HASH_TABLE [HTTP_REQUEST_HANDLER, STRING] local a_handler: HTTP_REQUEST_HANDLER once diff --git a/shared_uri_contents_types.e b/src/shared_uri_contents_types.e similarity index 100% rename from shared_uri_contents_types.e rename to src/shared_uri_contents_types.e diff --git a/tcp_stream_socket.e b/src/tcp_stream_socket.e similarity index 86% rename from tcp_stream_socket.e rename to src/tcp_stream_socket.e index 8647c27f..ce9068b9 100644 --- a/tcp_stream_socket.e +++ b/src/tcp_stream_socket.e @@ -1,11 +1,11 @@ note description: "Summary description for {TCP_STREAM_SOCKET}." - author: "" date: "$Date$" revision: "$Revision$" class TCP_STREAM_SOCKET + inherit NETWORK_STREAM_SOCKET @@ -15,7 +15,8 @@ create create {NETWORK_STREAM_SOCKET} make_from_descriptor_and_address -feature +feature -- Basic operation + send_message (a_msg: STRING) local a_package : PACKET @@ -25,6 +26,7 @@ feature 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) - Current.send (a_package, 1) + send (a_package, 1) end + end diff --git a/uri_contents_types.e b/src/uri_contents_types.e similarity index 100% rename from uri_contents_types.e rename to src/uri_contents_types.e diff --git a/web_server/application.e b/web_server/application.e new file mode 100644 index 00000000..a44e1b1d --- /dev/null +++ b/web_server/application.e @@ -0,0 +1,37 @@ +note + description : "nino application root class" + date : "$Date$" + revision : "$Revision$" + +class + APPLICATION + +inherit + ARGUMENTS + +create + make + +feature {NONE} -- Initialization + + make + -- Run application. + local + l_server : HTTP_SERVER + l_cfg: HTTP_SERVER_CONFIGURATION + l_http_handler : HTTP_HANDLER + do + create l_cfg.make + l_cfg.http_server_port := 9_000 + l_cfg.document_root := default_document_root + + create l_server.make (l_cfg) + create {APPLICATION_CONNECTION_HANDLER} l_http_handler.make (l_server, "HTTP_HANDLER") + l_server.setup (l_http_handler) + end + +feature -- Access + + default_document_root: STRING = "webroot" + +end diff --git a/web_server/application_handler.e b/web_server/application_handler.e new file mode 100644 index 00000000..78277160 --- /dev/null +++ b/web_server/application_handler.e @@ -0,0 +1,61 @@ +note + description: "Summary description for {HTTP_CONNECTION_HANDLER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + APPLICATION_CONNECTION_HANDLER + +inherit + HTTP_CONNECTION_HANDLER + +create + make + +feature -- Request processing + + process_request (a_handler: HTTP_CONNECTION_HANDLER; a_input: HTTP_INPUT_STREAM; a_output: HTTP_OUTPUT_STREAM) + -- Process request ... + local + a_method: STRING + do + a_method := a_handler.method + + if a_method.is_equal (Get) then + execute_get_request (a_handler.uri, a_handler.request_header_map, a_handler.request_header, a_input, a_output) + elseif a_method.is_equal (Post) then + execute_post_request (a_handler.uri, a_handler.request_header_map, a_handler.request_header, a_input, a_output) + elseif a_method.is_equal (Put) then + elseif a_method.is_equal (Options) then + elseif a_method.is_equal (Head) then + elseif a_method.is_equal (Delete) then + elseif a_method.is_equal (Trace) then + elseif a_method.is_equal (Connect) then + else + debug + print ("Method [" + a_method + "] not supported") + end + end + end + + execute_get_request (a_uri: STRING; a_headers_map: HASH_TABLE [STRING, STRING]; a_headers_text: STRING; a_input: HTTP_INPUT_STREAM; a_output: HTTP_OUTPUT_STREAM) + local + l_http_request : HTTP_REQUEST_HANDLER + do + create {GET_REQUEST_HANDLER} l_http_request.make (a_input, a_output) + l_http_request.set_uri (a_uri) + l_http_request.process + end + + execute_post_request (a_uri: STRING; a_headers_map: HASH_TABLE [STRING, STRING]; a_headers_text: STRING; a_input: HTTP_INPUT_STREAM; a_output: HTTP_OUTPUT_STREAM) + local + l_http_request : HTTP_REQUEST_HANDLER + do + check not_yet_implemented: False end + create {POST_REQUEST_HANDLER} l_http_request.make (a_input, a_output) + l_http_request.set_uri (a_uri) + l_http_request.process + end + +end diff --git a/web_server/web_server.ecf b/web_server/web_server.ecf new file mode 100644 index 00000000..826dfa8b --- /dev/null +++ b/web_server/web_server.ecf @@ -0,0 +1,21 @@ + + + + + + /EIFGENs$ + /CVS$ + /.svn$ + /.git$ + + + + + + + + + + diff --git a/webroot/demo1/img/gradient_light.jpg b/web_server/webroot/demo1/img/gradient_light.jpg similarity index 100% rename from webroot/demo1/img/gradient_light.jpg rename to web_server/webroot/demo1/img/gradient_light.jpg diff --git a/webroot/demo1/jquery.scrollTo-1.4.2/changes.txt b/web_server/webroot/demo1/jquery.scrollTo-1.4.2/changes.txt similarity index 100% rename from webroot/demo1/jquery.scrollTo-1.4.2/changes.txt rename to web_server/webroot/demo1/jquery.scrollTo-1.4.2/changes.txt diff --git a/webroot/demo1/jquery.scrollTo-1.4.2/jquery.scrollTo-min.js b/web_server/webroot/demo1/jquery.scrollTo-1.4.2/jquery.scrollTo-min.js similarity index 100% rename from webroot/demo1/jquery.scrollTo-1.4.2/jquery.scrollTo-min.js rename to web_server/webroot/demo1/jquery.scrollTo-1.4.2/jquery.scrollTo-min.js diff --git a/webroot/demo1/jquery.scrollTo-1.4.2/jquery.scrollTo.js b/web_server/webroot/demo1/jquery.scrollTo-1.4.2/jquery.scrollTo.js similarity index 100% rename from webroot/demo1/jquery.scrollTo-1.4.2/jquery.scrollTo.js rename to web_server/webroot/demo1/jquery.scrollTo-1.4.2/jquery.scrollTo.js diff --git a/webroot/demo1/script.js b/web_server/webroot/demo1/script.js similarity index 100% rename from webroot/demo1/script.js rename to web_server/webroot/demo1/script.js diff --git a/webroot/demo1/styles.css b/web_server/webroot/demo1/styles.css similarity index 100% rename from webroot/demo1/styles.css rename to web_server/webroot/demo1/styles.css diff --git a/webroot/demo1/template.html b/web_server/webroot/demo1/template.html similarity index 100% rename from webroot/demo1/template.html rename to web_server/webroot/demo1/template.html diff --git a/webroot/demo2/demo.html b/web_server/webroot/demo2/demo.html similarity index 100% rename from webroot/demo2/demo.html rename to web_server/webroot/demo2/demo.html diff --git a/webroot/demo2/img/background.jpg b/web_server/webroot/demo2/img/background.jpg similarity index 100% rename from webroot/demo2/img/background.jpg rename to web_server/webroot/demo2/img/background.jpg diff --git a/webroot/demo2/img/button_bg.jpg b/web_server/webroot/demo2/img/button_bg.jpg similarity index 100% rename from webroot/demo2/img/button_bg.jpg rename to web_server/webroot/demo2/img/button_bg.jpg diff --git a/webroot/demo2/img/dot.png b/web_server/webroot/demo2/img/dot.png similarity index 100% rename from webroot/demo2/img/dot.png rename to web_server/webroot/demo2/img/dot.png diff --git a/webroot/demo2/script.js b/web_server/webroot/demo2/script.js similarity index 100% rename from webroot/demo2/script.js rename to web_server/webroot/demo2/script.js diff --git a/webroot/demo2/styles.css b/web_server/webroot/demo2/styles.css similarity index 100% rename from webroot/demo2/styles.css rename to web_server/webroot/demo2/styles.css diff --git a/webroot/example/fonts/DINMittelschriftStd.otf b/web_server/webroot/example/fonts/DINMittelschriftStd.otf similarity index 100% rename from webroot/example/fonts/DINMittelschriftStd.otf rename to web_server/webroot/example/fonts/DINMittelschriftStd.otf diff --git a/webroot/example/fonts/MyriadPro-LightCond.otf b/web_server/webroot/example/fonts/MyriadPro-LightCond.otf similarity index 100% rename from webroot/example/fonts/MyriadPro-LightCond.otf rename to web_server/webroot/example/fonts/MyriadPro-LightCond.otf diff --git a/webroot/example/fonts/MyriadPro-SemiboldCond.otf b/web_server/webroot/example/fonts/MyriadPro-SemiboldCond.otf similarity index 100% rename from webroot/example/fonts/MyriadPro-SemiboldCond.otf rename to web_server/webroot/example/fonts/MyriadPro-SemiboldCond.otf diff --git a/webroot/example/fonts/stan0755.ttf b/web_server/webroot/example/fonts/stan0755.ttf similarity index 100% rename from webroot/example/fonts/stan0755.ttf rename to web_server/webroot/example/fonts/stan0755.ttf diff --git a/webroot/example/fonts/tahoma.ttf b/web_server/webroot/example/fonts/tahoma.ttf similarity index 100% rename from webroot/example/fonts/tahoma.ttf rename to web_server/webroot/example/fonts/tahoma.ttf diff --git a/webroot/example/fonts/tahomabd.ttf b/web_server/webroot/example/fonts/tahomabd.ttf similarity index 100% rename from webroot/example/fonts/tahomabd.ttf rename to web_server/webroot/example/fonts/tahomabd.ttf diff --git a/webroot/example/fonts/trebuc.ttf b/web_server/webroot/example/fonts/trebuc.ttf similarity index 100% rename from webroot/example/fonts/trebuc.ttf rename to web_server/webroot/example/fonts/trebuc.ttf diff --git a/webroot/example/fonts/trebucbd.ttf b/web_server/webroot/example/fonts/trebucbd.ttf similarity index 100% rename from webroot/example/fonts/trebucbd.ttf rename to web_server/webroot/example/fonts/trebucbd.ttf diff --git a/webroot/example/html/contentpage.html b/web_server/webroot/example/html/contentpage.html similarity index 100% rename from webroot/example/html/contentpage.html rename to web_server/webroot/example/html/contentpage.html diff --git a/webroot/example/html/css/styles.css b/web_server/webroot/example/html/css/styles.css similarity index 100% rename from webroot/example/html/css/styles.css rename to web_server/webroot/example/html/css/styles.css diff --git a/webroot/example/html/images/b_footer.jpg b/web_server/webroot/example/html/images/b_footer.jpg similarity index 100% rename from webroot/example/html/images/b_footer.jpg rename to web_server/webroot/example/html/images/b_footer.jpg diff --git a/webroot/example/html/images/btn_1.jpg b/web_server/webroot/example/html/images/btn_1.jpg similarity index 100% rename from webroot/example/html/images/btn_1.jpg rename to web_server/webroot/example/html/images/btn_1.jpg diff --git a/webroot/example/html/images/btn_1_over.jpg b/web_server/webroot/example/html/images/btn_1_over.jpg similarity index 100% rename from webroot/example/html/images/btn_1_over.jpg rename to web_server/webroot/example/html/images/btn_1_over.jpg diff --git a/webroot/example/html/images/btn_2.jpg b/web_server/webroot/example/html/images/btn_2.jpg similarity index 100% rename from webroot/example/html/images/btn_2.jpg rename to web_server/webroot/example/html/images/btn_2.jpg diff --git a/webroot/example/html/images/btn_2_over.jpg b/web_server/webroot/example/html/images/btn_2_over.jpg similarity index 100% rename from webroot/example/html/images/btn_2_over.jpg rename to web_server/webroot/example/html/images/btn_2_over.jpg diff --git a/webroot/example/html/images/btn_3.jpg b/web_server/webroot/example/html/images/btn_3.jpg similarity index 100% rename from webroot/example/html/images/btn_3.jpg rename to web_server/webroot/example/html/images/btn_3.jpg diff --git a/webroot/example/html/images/btn_3_over.jpg b/web_server/webroot/example/html/images/btn_3_over.jpg similarity index 100% rename from webroot/example/html/images/btn_3_over.jpg rename to web_server/webroot/example/html/images/btn_3_over.jpg diff --git a/webroot/example/html/images/btn_4.jpg b/web_server/webroot/example/html/images/btn_4.jpg similarity index 100% rename from webroot/example/html/images/btn_4.jpg rename to web_server/webroot/example/html/images/btn_4.jpg diff --git a/webroot/example/html/images/btn_4_over.jpg b/web_server/webroot/example/html/images/btn_4_over.jpg similarity index 100% rename from webroot/example/html/images/btn_4_over.jpg rename to web_server/webroot/example/html/images/btn_4_over.jpg diff --git a/webroot/example/html/images/btn_5.jpg b/web_server/webroot/example/html/images/btn_5.jpg similarity index 100% rename from webroot/example/html/images/btn_5.jpg rename to web_server/webroot/example/html/images/btn_5.jpg diff --git a/webroot/example/html/images/btn_5_over.jpg b/web_server/webroot/example/html/images/btn_5_over.jpg similarity index 100% rename from webroot/example/html/images/btn_5_over.jpg rename to web_server/webroot/example/html/images/btn_5_over.jpg diff --git a/webroot/example/html/images/btn_6.jpg b/web_server/webroot/example/html/images/btn_6.jpg similarity index 100% rename from webroot/example/html/images/btn_6.jpg rename to web_server/webroot/example/html/images/btn_6.jpg diff --git a/webroot/example/html/images/btn_6_over.jpg b/web_server/webroot/example/html/images/btn_6_over.jpg similarity index 100% rename from webroot/example/html/images/btn_6_over.jpg rename to web_server/webroot/example/html/images/btn_6_over.jpg diff --git a/webroot/example/html/images/client_login.jpg b/web_server/webroot/example/html/images/client_login.jpg similarity index 100% rename from webroot/example/html/images/client_login.jpg rename to web_server/webroot/example/html/images/client_login.jpg diff --git a/webroot/example/html/images/lines-07.jpg b/web_server/webroot/example/html/images/lines-07.jpg similarity index 100% rename from webroot/example/html/images/lines-07.jpg rename to web_server/webroot/example/html/images/lines-07.jpg diff --git a/webroot/example/html/images/lines-09.jpg b/web_server/webroot/example/html/images/lines-09.jpg similarity index 100% rename from webroot/example/html/images/lines-09.jpg rename to web_server/webroot/example/html/images/lines-09.jpg diff --git a/webroot/example/html/images/lines-11.jpg b/web_server/webroot/example/html/images/lines-11.jpg similarity index 100% rename from webroot/example/html/images/lines-11.jpg rename to web_server/webroot/example/html/images/lines-11.jpg diff --git a/webroot/example/html/images/lines-13.jpg b/web_server/webroot/example/html/images/lines-13.jpg similarity index 100% rename from webroot/example/html/images/lines-13.jpg rename to web_server/webroot/example/html/images/lines-13.jpg diff --git a/webroot/example/html/images/lines.jpg b/web_server/webroot/example/html/images/lines.jpg similarity index 100% rename from webroot/example/html/images/lines.jpg rename to web_server/webroot/example/html/images/lines.jpg diff --git a/webroot/example/html/images/main-03.jpg b/web_server/webroot/example/html/images/main-03.jpg similarity index 100% rename from webroot/example/html/images/main-03.jpg rename to web_server/webroot/example/html/images/main-03.jpg diff --git a/webroot/example/html/images/main-15.jpg b/web_server/webroot/example/html/images/main-15.jpg similarity index 100% rename from webroot/example/html/images/main-15.jpg rename to web_server/webroot/example/html/images/main-15.jpg diff --git a/webroot/example/html/images/main.jpg b/web_server/webroot/example/html/images/main.jpg similarity index 100% rename from webroot/example/html/images/main.jpg rename to web_server/webroot/example/html/images/main.jpg diff --git a/webroot/example/html/images/news-19.jpg b/web_server/webroot/example/html/images/news-19.jpg similarity index 100% rename from webroot/example/html/images/news-19.jpg rename to web_server/webroot/example/html/images/news-19.jpg diff --git a/webroot/example/html/images/news-20.jpg b/web_server/webroot/example/html/images/news-20.jpg similarity index 100% rename from webroot/example/html/images/news-20.jpg rename to web_server/webroot/example/html/images/news-20.jpg diff --git a/webroot/example/html/images/news.jpg b/web_server/webroot/example/html/images/news.jpg similarity index 100% rename from webroot/example/html/images/news.jpg rename to web_server/webroot/example/html/images/news.jpg diff --git a/webroot/example/html/images/services-23.jpg b/web_server/webroot/example/html/images/services-23.jpg similarity index 100% rename from webroot/example/html/images/services-23.jpg rename to web_server/webroot/example/html/images/services-23.jpg diff --git a/webroot/example/html/images/services-25.jpg b/web_server/webroot/example/html/images/services-25.jpg similarity index 100% rename from webroot/example/html/images/services-25.jpg rename to web_server/webroot/example/html/images/services-25.jpg diff --git a/webroot/example/html/images/services.jpg b/web_server/webroot/example/html/images/services.jpg similarity index 100% rename from webroot/example/html/images/services.jpg rename to web_server/webroot/example/html/images/services.jpg diff --git a/webroot/example/html/images/spotlight-24.jpg b/web_server/webroot/example/html/images/spotlight-24.jpg similarity index 100% rename from webroot/example/html/images/spotlight-24.jpg rename to web_server/webroot/example/html/images/spotlight-24.jpg diff --git a/webroot/example/html/images/spotlight.jpg b/web_server/webroot/example/html/images/spotlight.jpg similarity index 100% rename from webroot/example/html/images/spotlight.jpg rename to web_server/webroot/example/html/images/spotlight.jpg diff --git a/webroot/example/html/images/welcome-18.jpg b/web_server/webroot/example/html/images/welcome-18.jpg similarity index 100% rename from webroot/example/html/images/welcome-18.jpg rename to web_server/webroot/example/html/images/welcome-18.jpg diff --git a/webroot/example/html/images/welcome.jpg b/web_server/webroot/example/html/images/welcome.jpg similarity index 100% rename from webroot/example/html/images/welcome.jpg rename to web_server/webroot/example/html/images/welcome.jpg diff --git a/webroot/example/html/index.html b/web_server/webroot/example/html/index.html similarity index 100% rename from webroot/example/html/index.html rename to web_server/webroot/example/html/index.html diff --git a/webroot/example/jpeg/template276.jpg b/web_server/webroot/example/jpeg/template276.jpg similarity index 100% rename from webroot/example/jpeg/template276.jpg rename to web_server/webroot/example/jpeg/template276.jpg diff --git a/webroot/example/psd/index.psd b/web_server/webroot/example/psd/index.psd similarity index 100% rename from webroot/example/psd/index.psd rename to web_server/webroot/example/psd/index.psd diff --git a/webroot/example/readme.html b/web_server/webroot/example/readme.html similarity index 100% rename from webroot/example/readme.html rename to web_server/webroot/example/readme.html diff --git a/webroot/html/images.html b/web_server/webroot/html/images.html similarity index 100% rename from webroot/html/images.html rename to web_server/webroot/html/images.html diff --git a/webroot/html/images/btn_1.jpg b/web_server/webroot/html/images/btn_1.jpg similarity index 100% rename from webroot/html/images/btn_1.jpg rename to web_server/webroot/html/images/btn_1.jpg diff --git a/webroot/html/images/pulpit.jpg b/web_server/webroot/html/images/pulpit.jpg similarity index 100% rename from webroot/html/images/pulpit.jpg rename to web_server/webroot/html/images/pulpit.jpg diff --git a/webroot/html/simple.html b/web_server/webroot/html/simple.html similarity index 100% rename from webroot/html/simple.html rename to web_server/webroot/html/simple.html diff --git a/webroot/html5/dataset.html b/web_server/webroot/html5/dataset.html similarity index 100% rename from webroot/html5/dataset.html rename to web_server/webroot/html5/dataset.html diff --git a/web_server/webroot/post/index.html b/web_server/webroot/post/index.html new file mode 100644 index 00000000..85df7158 --- /dev/null +++ b/web_server/webroot/post/index.html @@ -0,0 +1,19 @@ + + + POST example + + +

    POST example

    +
    +
    + + +
    + +
    +
    + + +
    + +