Compare commits
7 Commits
es_rev9926
...
es_rev9927
| Author | SHA1 | Date | |
|---|---|---|---|
| f12158e535 | |||
| 080881368a | |||
|
|
3e935c7e33 | ||
|
|
ad2bb0d1a7 | ||
| 7a546622bc | |||
| aed7461faf | |||
| 56819d6793 |
@@ -17,10 +17,21 @@ create
|
||||
make_server_by_port
|
||||
|
||||
create {NETWORK_STREAM_SOCKET}
|
||||
make_from_descriptor_and_address
|
||||
make_from_descriptor_and_address,
|
||||
make_empty
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make_server_by_address_and_port (a_address: INET_ADDRESS; a_port: INTEGER)
|
||||
-- Create server socket on `a_address' and `a_port'.
|
||||
require
|
||||
valid_port: a_port >= 0
|
||||
do
|
||||
make
|
||||
create address.make_from_address_and_port (a_address, a_port)
|
||||
bind
|
||||
end
|
||||
|
||||
make
|
||||
-- Create a network stream socket.
|
||||
do
|
||||
@@ -28,16 +39,6 @@ feature {NONE} -- Initialization
|
||||
set_reuse_address
|
||||
end
|
||||
|
||||
make_server_by_address_and_port (an_address: INET_ADDRESS; a_port: INTEGER)
|
||||
-- Create server socket on `an_address' and `a_port'.
|
||||
require
|
||||
valid_port: a_port >= 0
|
||||
do
|
||||
make
|
||||
create address.make_from_address_and_port (an_address, a_port)
|
||||
bind
|
||||
end
|
||||
|
||||
feature -- Basic operation
|
||||
|
||||
send_message (a_msg: STRING)
|
||||
@@ -29,16 +29,6 @@ feature {NONE} -- Initialization
|
||||
set_reuse_address
|
||||
end
|
||||
|
||||
make_server_by_address_and_port (an_address: INET_ADDRESS; a_port: INTEGER)
|
||||
-- Create server socket on `an_address' and `a_port'.
|
||||
require
|
||||
valid_port: a_port >= 0
|
||||
do
|
||||
make
|
||||
create address.make_from_address_and_port (an_address, a_port)
|
||||
bind
|
||||
end
|
||||
|
||||
feature -- Basic operation
|
||||
|
||||
send_message (a_msg: STRING)
|
||||
|
||||
@@ -22,13 +22,13 @@
|
||||
<file_rule>
|
||||
<exclude>tcp_stream_socket.e</exclude>
|
||||
<condition>
|
||||
<version type="compiler" max="15.01.9.6506"/>
|
||||
<version type="compiler" max="16.11"/>
|
||||
</condition>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
<cluster name="spec_before_15_01" location=".\library\spec\before_15_01\" recursive="true">
|
||||
<cluster name="spec_until_16_05" location=".\library\spec\until_16_05\" recursive="true">
|
||||
<condition>
|
||||
<version type="compiler" max="15.01.9.6506"/>
|
||||
<version type="compiler" max="16.11"/>
|
||||
</condition>
|
||||
</cluster>
|
||||
</target>
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
<?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="nino" uuid="32C1D67D-33DE-4F1E-864B-D45388F2E3E6" library_target="nino">
|
||||
<target name="nino">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" void_safety="none">
|
||||
<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.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=".\library\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>spec</exclude>
|
||||
</file_rule>
|
||||
<file_rule>
|
||||
<exclude>tcp_stream_socket.e</exclude>
|
||||
<condition>
|
||||
<version type="compiler" max="15.01.9.6506"/>
|
||||
</condition>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
<cluster name="spec_before_15_01" location=".\library\spec\before_15_01\" recursive="true">
|
||||
<condition>
|
||||
<version type="compiler" max="15.01.9.6506"/>
|
||||
</condition>
|
||||
</cluster>
|
||||
</target>
|
||||
</system>
|
||||
<?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="nino" uuid="32C1D67D-33DE-4F1E-864B-D45388F2E3E6" library_target="nino">
|
||||
<target name="nino">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" void_safety="none">
|
||||
<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.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=".\library\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>spec</exclude>
|
||||
</file_rule>
|
||||
<file_rule>
|
||||
<exclude>tcp_stream_socket.e</exclude>
|
||||
<condition>
|
||||
<version type="compiler" max="16.11"/>
|
||||
</condition>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
<cluster name="spec_until_16_05" location=".\library\spec\until_16_05\" recursive="true">
|
||||
<condition>
|
||||
<version type="compiler" max="16.11"/>
|
||||
</condition>
|
||||
</cluster>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -1,22 +1,29 @@
|
||||
The main goal of the connectors is to let you choose a target at compile time.
|
||||
This allows you to concentrate on your business during development time and then decide which target you choose at deployment time.
|
||||
The current connectors are:
|
||||
* Nino
|
||||
* Standalone
|
||||
* FastCGI
|
||||
* CGI
|
||||
* OpenShift
|
||||
* Nino (obsolete, replaced by Standalone)
|
||||
|
||||
The most widely used workflow is to use Nino on your development machine and FastCGI on your production server.
|
||||
Nino being a web server written entirely in Eiffel, you can inspect your HTTP requests and respones in EiffelStudio which is great during development.
|
||||
The most widely used workflow is to use Standalone on your development machine and FastCGI on your production server.
|
||||
Standalone being a web server written entirely in Eiffel, you can inspect your HTTP requests and respones in EiffelStudio which is great during development.
|
||||
On the other hand, FastCGI is great at handling concurrent requests and coupled with Apache (or another web production server), you don't even need to worry about the lifecyle of your application (creation and destruction) as Apache will do it for you!
|
||||
|
||||
Let's now dig into each of the connecters.
|
||||
|
||||
# Nino
|
||||
# Standalone
|
||||
|
||||
EiffelWeb standalone is connector based on the EiffelWeb httpd server entirely written in Eiffel
|
||||
(note: httpd is under standalone connector, so you can consider Standalone as the EiffelWeb standalone web server).
|
||||
The goal of Standalone is to provide a simple web server for development (like Java, Python and Ruby provide).
|
||||
|
||||
# Nino (obsolete and replaced by Standalone)
|
||||
|
||||
Nino is a web server entirely written in Eiffel.
|
||||
The goal of Nino is to provide a simple web server for development (like Java, Python and Ruby provide).
|
||||
Nino is currently maintained by Javier Velilla and the repository can be found here: https://github.com/jvelilla/EiffelWebNino
|
||||
Nino is currently maintained by Jocelyn Fiat and Javier Velilla and the repository can be found here: https://github.com/jvelilla/EiffelWebNino
|
||||
|
||||
# FastCGI
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ Using EWF, your service is built on top of underlying httpd solution/connectors.
|
||||
Currently 3 main connectors are available:
|
||||
* __CGI__: following the CGI interface, this is an easy solution to run the service on any platform.
|
||||
* __libFCGI__: based on the libfcgi solution, this can be used with Apache, IIS, nginx, ...
|
||||
* __nino__: a standalone server: Eiffel Web Nino allow you to embed a web server anywhere, on any platform without any dependencies on other httpd server.
|
||||
* __standalone__: a standalone server: EiffelWeb Standalone web server allows you to embed a web server anywhere, on any platform without any dependencies on other httpd server.
|
||||
|
||||
At compilation time, you can use a default connector (by using the associated default lib), but you can also use a mixed of them and choose which one to execute at runtime.
|
||||
It is fairly easy to add new connector, it just has to follow the EWSGI interface
|
||||
|
||||
@@ -4,7 +4,7 @@ Now you have to implement each handler. You need to inherit from WSF_SKELETON_HA
|
||||
|
||||
## Communicating between routines
|
||||
|
||||
Depending upon the connector (Nino, CGI, FastCGI etc.) that you are using, your handler may be invoked concurrently for multiple requests. Therefore it is unsafe to save state in normal attributes. WSF_REQUEST has a pair of getter/setter routines, execution_variable/set_execution_variable, which you can use for this purpose.
|
||||
Depending upon the connector (Standalone, CGI, FastCGI etc.) that you are using, your handler may be invoked concurrently for multiple requests. Therefore it is unsafe to save state in normal attributes. WSF_REQUEST has a pair of getter/setter routines, execution_variable/set_execution_variable, which you can use for this purpose.
|
||||
Internally, the framework uses the following execution variable names, so you must avoid them:
|
||||
|
||||
1. REQUEST_ENTITY
|
||||
|
||||
@@ -59,7 +59,7 @@ feature -- Basic operations
|
||||
end
|
||||
```
|
||||
|
||||
When using the "nino" connector or the new "standalone" connector, by default the service listens on port 80, but often this port is already used by other applications, so it is recommended to use another port.
|
||||
When using the "standalone" connector (or the deprecated "nino" connector), by default the service listens on port 80, but often this port is already used by other applications, so it is recommended to use another port.
|
||||
To define another port, redefine the feature `initialize' and set up a new port number using the service options (see below).
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ The **WSF_REQUEST** gives access to the incoming data; the class provides featur
|
||||
|
||||
The **WSF_RESPONSE** provides features to define the response with information such as HTTP status codes (10x,20x, 30x, 40x, and 50x), response headers (Content-Type, Content-Length, etc.) and obviously the body of the message itself.
|
||||
|
||||
**APPLICATION** is the root class of our example, it launches the application, using the corresponding connector, Which connector? this depends how you want to run it cgi, fcgi,nino or standalone. For development is recommended to use a standalone web server written in Eiffel, and run the execution within the EiffelStudio debugger. For production fcgi (or cgi) using Apache or another popular web server.
|
||||
**APPLICATION** is the root class of our example, it launches the application, using the corresponding connector, Which connector? this depends how you want to run it cgi, fcgi,standalone. For development is recommended to use a standalone web server written in Eiffel, and run the execution within the EiffelStudio debugger. For production fcgi (or cgi) using Apache or another popular web server.
|
||||
|
||||

|
||||
|
||||
@@ -149,9 +149,10 @@ The source code is available on Github. You can get it by running the command:
|
||||
|
||||
```git clone https://github.com/EiffelWebFramework/ewf.git```
|
||||
|
||||
The example of simple service that generate plain text response is located in the directory $PATH/ewf/doc/workbook/basics/simple, where $PATH is where you run ```git clone``` . Just double click on the simple.ecf file and select the simple_nino target or if you prefer the command line, run the command:
|
||||
The example of simple service that generate plain text response is located in the directory $PATH/ewf/doc/workbook/basics/simple, where $PATH is where you run ```git clone``` .
|
||||
Just double click on the simple.ecf file and select the simple_standalone target or if you prefer the command line, run the command:
|
||||
|
||||
```estudio -config simple.ecf -target simple_nino```
|
||||
```estudio -config simple.ecf -target simple_standalone```
|
||||
|
||||
<a name="html"></a>
|
||||
|
||||
@@ -204,9 +205,10 @@ The source code is available on Github. You can get it by running the command:
|
||||
|
||||
```git clone https://github.com/EiffelWebFramework/ewf.git```
|
||||
|
||||
The example of the service that generates HTML is located in the directory $PATH/ewf/doc/workbook/basics/simple_html, where $PATH is where you run ```git clone``` . Just double click on the simple_html.ecf file and select the simple_html_nino target or if you prefer the command line, run the command:
|
||||
The example of the service that generates HTML is located in the directory $PATH/ewf/doc/workbook/basics/simple_html, where $PATH is where you run ```git clone``` .
|
||||
Just double click on the simple_html.ecf file and select the simple_html_standalone target or if you prefer the command line, run the command:
|
||||
|
||||
```estudio -config simple_html.ecf -target simple_html_nino```
|
||||
```estudio -config simple_html.ecf -target simple_html_standalone```
|
||||
|
||||
Nav: [Workbook](../workbook.md) :: [Handling Requests: Form/Query Parameter](../handling_request/form.md)
|
||||
|
||||
|
||||
@@ -13,14 +13,6 @@
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
|
||||
</target>
|
||||
<target name="simple_nino" extends="common">
|
||||
<root class="APPLICATION" feature="make_and_launch"/>
|
||||
<option warning="true" is_attached_by_default="true" void_safety="transitional" syntax="transitional">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<library name="default_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\nino-safe.ecf"/>
|
||||
<cluster name="simple" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="simple_cgi" extends="common">
|
||||
<root class="APPLICATION" feature="make_and_launch"/>
|
||||
<option warning="true" is_attached_by_default="true" void_safety="transitional" syntax="transitional">
|
||||
@@ -45,6 +37,6 @@
|
||||
<library name="default_standalone" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\standalone-safe.ecf"/>
|
||||
<cluster name="simple" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="simple" extends="simple_nino">
|
||||
<target name="simple" extends="simple_standalone">
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
|
||||
</target>
|
||||
<target name="simple_html_nino" extends="common">
|
||||
<target name="simple_html_standalone" extends="common">
|
||||
<root class="APPLICATION" feature="make_and_launch"/>
|
||||
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<library name="default_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\nino-safe.ecf"/>
|
||||
<library name="default_standalone" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\standalone-safe.ecf"/>
|
||||
<cluster name="simple_html" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="simple_html_cgi" extends="common">
|
||||
@@ -37,6 +37,6 @@
|
||||
<library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
|
||||
<cluster name="simple_html" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="simple_html" extends="simple_html_nino">
|
||||
<target name="simple_html" extends="simple_html_standalone">
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
|
||||
</target>
|
||||
<target name="exel_nino" extends="common">
|
||||
<target name="exel_standalone" extends="common">
|
||||
<root class="APPLICATION" feature="make_and_launch"/>
|
||||
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<library name="default_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\nino-safe.ecf"/>
|
||||
<library name="default_standalone" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\standalone-safe.ecf"/>
|
||||
<cluster name="exel" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="exel_cgi" extends="common">
|
||||
@@ -37,6 +37,6 @@
|
||||
<library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
|
||||
<cluster name="exel" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="exel" extends="exel_nino">
|
||||
<target name="exel" extends="exel_standalone">
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
"1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-10-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-10-0 http://www.eiffel.com/developers/xml/configuration-1-10-0.xsd" name="headers" uuid="C28C4F53-9963-46C0-A080-8F13E94E7486" library_target="headers">
|
||||
<target name="common" abstract="true">
|
||||
<file_rule>
|
||||
@@ -13,12 +13,12 @@
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
|
||||
</target>
|
||||
<target name="headers_nino" extends="common">
|
||||
<target name="headers_standalone" extends="common">
|
||||
<root class="APPLICATION" feature="make_and_launch"/>
|
||||
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<library name="default_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\nino-safe.ecf"/>
|
||||
<library name="default_standalone" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\standalone-safe.ecf"/>
|
||||
<cluster name="headers" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="headers_cgi" extends="common">
|
||||
@@ -37,6 +37,6 @@
|
||||
<library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
|
||||
<cluster name="headers" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="headers" extends="headers_nino">
|
||||
<target name="headers" extends="headers_standalone">
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
|
||||
</target>
|
||||
<target name="search_nino" extends="common">
|
||||
<target name="search_standalone" extends="common">
|
||||
<root class="APPLICATION" feature="make_and_launch"/>
|
||||
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<library name="default_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\nino-safe.ecf"/>
|
||||
<library name="default_standalone" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\standalone-safe.ecf"/>
|
||||
<cluster name="search" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="search_cgi" extends="common">
|
||||
@@ -37,6 +37,6 @@
|
||||
<library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
|
||||
<cluster name="search" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="search" extends="search_nino">
|
||||
<target name="search" extends="search_standalone">
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
|
||||
</target>
|
||||
<target name="status_nino" extends="common">
|
||||
<target name="status_standalone" extends="common">
|
||||
<root class="APPLICATION" feature="make_and_launch"/>
|
||||
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<library name="default_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\nino-safe.ecf"/>
|
||||
<library name="default_standalone" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\standalone-safe.ecf"/>
|
||||
<cluster name="status" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="status_cgi" extends="common">
|
||||
@@ -37,6 +37,6 @@
|
||||
<library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
|
||||
<cluster name="status" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="status" extends="status_nino">
|
||||
<target name="status" extends="status_standalone">
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
|
||||
</target>
|
||||
<target name="example_nino" extends="common">
|
||||
<target name="example_standalone" extends="common">
|
||||
<root class="APPLICATION" feature="make_and_launch"/>
|
||||
<option warning="true" is_attached_by_default="true" void_safety="transitional" syntax="transitional">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<library name="default_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\nino-safe.ecf"/>
|
||||
<library name="default_standalone" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\standalone-safe.ecf"/>
|
||||
<cluster name="example" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="example_cgi" extends="common">
|
||||
@@ -37,6 +37,6 @@
|
||||
<library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
|
||||
<cluster name="example" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="example" extends="example_nino">
|
||||
<target name="example" extends="example_standalone">
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
|
||||
</target>
|
||||
<target name="form_nino" extends="common">
|
||||
<target name="form_standalone" extends="common">
|
||||
<root class="APPLICATION" feature="make_and_launch"/>
|
||||
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<library name="default_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\nino-safe.ecf"/>
|
||||
<library name="default_standalone" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\standalone-safe.ecf"/>
|
||||
<cluster name="form" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="form_cgi" extends="common">
|
||||
@@ -37,6 +37,6 @@
|
||||
<library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
|
||||
<cluster name="form" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="form" extends="form_nino">
|
||||
<target name="form" extends="form_standalone">
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
|
||||
</target>
|
||||
<target name="form_nino" extends="common">
|
||||
<target name="form_standalone" extends="common">
|
||||
<root class="APPLICATION" feature="make_and_launch"/>
|
||||
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<library name="default_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\nino-safe.ecf"/>
|
||||
<library name="default_standalone" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\standalone-safe.ecf"/>
|
||||
<cluster name="form" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="form_cgi" extends="common">
|
||||
@@ -37,6 +37,6 @@
|
||||
<library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
|
||||
<cluster name="form" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="form" extends="form_nino">
|
||||
<target name="form" extends="form_standalone">
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
|
||||
</target>
|
||||
<target name="browsers_nino" extends="common">
|
||||
<target name="browsers_standalone" extends="common">
|
||||
<root class="APPLICATION" feature="make_and_launch"/>
|
||||
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<library name="default_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\nino-safe.ecf"/>
|
||||
<library name="default_standalone" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\standalone-safe.ecf"/>
|
||||
<cluster name="browsers" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="browsers_cgi" extends="common">
|
||||
@@ -37,6 +37,6 @@
|
||||
<library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
|
||||
<cluster name="browsers" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="browsers" extends="browsers_nino">
|
||||
<target name="browsers" extends="browsers_standalone">
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
|
||||
</target>
|
||||
<target name="cgi_variables_nino" extends="common">
|
||||
<target name="cgi_variables_standalone" extends="common">
|
||||
<root class="APPLICATION" feature="make_and_launch"/>
|
||||
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<library name="default_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\nino-safe.ecf"/>
|
||||
<library name="default_standalone" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\standalone-safe.ecf"/>
|
||||
<cluster name="cgi_variables" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="cgi_variables_cgi" extends="common">
|
||||
@@ -37,6 +37,6 @@
|
||||
<library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
|
||||
<cluster name="cgi_variables" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="cgi_variables" extends="cgi_variables_nino">
|
||||
<target name="cgi_variables" extends="cgi_variables_standalone">
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
|
||||
</target>
|
||||
<target name="header_fields_nino" extends="common">
|
||||
<target name="header_fields_standalone" extends="common">
|
||||
<root class="APPLICATION" feature="make_and_launch"/>
|
||||
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<library name="default_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\nino-safe.ecf"/>
|
||||
<library name="default_standalone" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\standalone-safe.ecf"/>
|
||||
<cluster name="header_fields" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="header_fields_cgi" extends="common">
|
||||
@@ -37,6 +37,6 @@
|
||||
<library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
|
||||
<cluster name="header_fields" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="header_fields" extends="header_fields_nino">
|
||||
<target name="header_fields" extends="header_fields_standalone">
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
|
||||
</target>
|
||||
<target name="upload_nino" extends="common">
|
||||
<target name="upload_standalone" extends="common">
|
||||
<root class="APPLICATION" feature="make_and_launch"/>
|
||||
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<library name="default_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\nino-safe.ecf"/>
|
||||
<library name="default_standalone" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\standalone-safe.ecf"/>
|
||||
<cluster name="upload" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="upload_cgi" extends="common">
|
||||
@@ -37,6 +37,6 @@
|
||||
<library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
|
||||
<cluster name="upload" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="upload" extends="upload_nino">
|
||||
<target name="upload" extends="upload_standalone">
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
<library name="wsf" location="..\..\..\..\..\..\library\server\wsf\wsf-safe.ecf"/>
|
||||
<library name="wsf_js_widget" location="..\..\wsf_js_widget-safe.ecf" readonly="false"/>
|
||||
</target>
|
||||
<target name="js_widget_template_nino" extends="common">
|
||||
<target name="js_widget_template_standalone" extends="common">
|
||||
<root class="APPLICATION" feature="make_and_launch"/>
|
||||
<library name="default_nino" location="..\..\..\..\..\..\library\server\wsf\default\nino-safe.ecf"/>
|
||||
<library name="default_standalone" location="..\..\..\..\..\..\library\server\wsf\default\standalone-safe.ecf"/>
|
||||
<cluster name="js_widget_template" location=".\src\" recursive="true">
|
||||
</cluster>
|
||||
</target>
|
||||
@@ -30,6 +30,6 @@
|
||||
<library name="default_libfcgi" location="..\..\..\..\..\..\library\server\wsf\default\libfcgi-safe.ecf"/>
|
||||
<cluster name="js_widget_template" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
<target name="js_widget_template" extends="js_widget_template_nino">
|
||||
<target name="js_widget_template" extends="js_widget_template_standalone">
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
<library name="wsf" location="..\..\..\..\..\..\library\server\wsf\wsf-safe.ecf"/>
|
||||
<library name="wsf_js_widget" location="..\..\wsf_js_widget-safe.ecf" readonly="false"/>
|
||||
</target>
|
||||
<target name="js_custom_widget_nino" extends="common">
|
||||
<target name="js_custom_widget_standalone" extends="common">
|
||||
<root class="APPLICATION" feature="make_and_launch"/>
|
||||
<library name="default_nino" location="..\..\..\..\..\..\library\server\wsf\default\nino-safe.ecf"/>
|
||||
<library name="default_standalone" location="..\..\..\..\..\..\library\server\wsf\default\standalone-safe.ecf"/>
|
||||
<cluster name="js_custom_widget" location=".\src\" recursive="true">
|
||||
</cluster>
|
||||
</target>
|
||||
@@ -30,6 +30,6 @@
|
||||
<library name="default_libfcgi" location="..\..\..\..\..\..\library\server\wsf\default\libfcgi-safe.ecf"/>
|
||||
<cluster name="js_custom_widget" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
<target name="js_custom_widget" extends="js_custom_widget_nino">
|
||||
<target name="js_custom_widget" extends="js_custom_widget_standalone">
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
<library name="wsf" location="..\..\..\..\..\..\library\server\wsf\wsf-safe.ecf"/>
|
||||
<library name="wsf_js_widget" location="..\..\wsf_js_widget-safe.ecf" readonly="false"/>
|
||||
</target>
|
||||
<target name="demo_nino" extends="common">
|
||||
<target name="demo_standalone" extends="common">
|
||||
<root class="APPLICATION" feature="make_and_launch"/>
|
||||
<option warning="true" is_attached_by_default="true" void_safety="transitional" syntax="transitional">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<library name="default_nino" location="..\..\..\..\..\..\library\server\wsf\default\nino-safe.ecf"/>
|
||||
<library name="default_standalone" location="..\..\..\..\..\..\library\server\wsf\default\standalone-safe.ecf"/>
|
||||
<cluster name="demo" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="demo_cgi" extends="common">
|
||||
@@ -40,6 +40,6 @@
|
||||
<library name="default_libfcgi" location="..\..\..\..\..\..\library\server\wsf\default\libfcgi-safe.ecf"/>
|
||||
<cluster name="demo" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="demo" extends="demo_nino">
|
||||
<target name="demo" extends="demo_standalone">
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<root class="${APP_ROOT}" feature="make_and_launch"/>
|
||||
<library name="cgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\cgi-safe.ecf"/>
|
||||
<library name="libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\libfcgi-safe.ecf"/>
|
||||
<library name="nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\nino-safe.ecf"/>
|
||||
<library name="standalone" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\standalone-safe.ecf"/>
|
||||
<cluster name="launcher" location=".\launcher\any\" recursive="true"/>
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
<target name="${APPNAME}_nino" extends="common">
|
||||
<target name="${APPNAME}_standalone" extends="common">
|
||||
<root class="${APP_ROOT}" feature="make_and_launch"/>
|
||||
<library name="default_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\nino-safe.ecf"/>
|
||||
<library name="default_standalone" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\standalone-safe.ecf"/>
|
||||
<cluster name="launcher" location=".\launcher\default\" recursive="true"/>
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
@@ -40,6 +40,6 @@
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
|
||||
<target name="${APPNAME}" extends="${APPNAME}_nino"/>
|
||||
<target name="${APPNAME}" extends="${APPNAME}_standalone"/>
|
||||
</system>
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<root class="${APP_ROOT}" feature="make_and_launch"/>
|
||||
<library name="cgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\cgi-safe.ecf"/>
|
||||
<library name="libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\libfcgi-safe.ecf"/>
|
||||
<library name="nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\nino-safe.ecf"/>
|
||||
<library name="standalone" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\standalone-safe.ecf"/>
|
||||
<cluster name="launcher" location=".\launcher\any\" recursive="true"/>
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
|
||||
@@ -22,8 +22,8 @@ feature -- Execution
|
||||
nature: like launcher_nature
|
||||
do
|
||||
nature := launcher_nature
|
||||
if nature = Void or else nature = nature_nino then
|
||||
launch_nino (a_service, opts)
|
||||
if nature = Void or else nature = nature_standalone then
|
||||
launch_standalone (a_service, opts)
|
||||
elseif nature = nature_cgi then
|
||||
launch_cgi (a_service, opts)
|
||||
elseif nature = nature_libfcgi then
|
||||
@@ -38,7 +38,7 @@ feature {NONE} -- Access
|
||||
|
||||
launcher_nature: detachable READABLE_STRING_8
|
||||
-- Initialize the launcher nature
|
||||
-- either cgi, libfcgi, or nino.
|
||||
-- either cgi, libfcgi, or standalone.
|
||||
--| We could extend with more connector if needed.
|
||||
--| and we could use WSF_DEFAULT_SERVICE_LAUNCHER to configure this at compilation time.
|
||||
local
|
||||
@@ -51,8 +51,8 @@ feature {NONE} -- Access
|
||||
ext := l_entry.extension
|
||||
end
|
||||
if ext /= Void then
|
||||
if ext.same_string (nature_nino) then
|
||||
Result := nature_nino
|
||||
if ext.same_string (nature_standalone) then
|
||||
Result := nature_standalone
|
||||
end
|
||||
if ext.same_string (nature_cgi) then
|
||||
Result := nature_cgi
|
||||
@@ -63,13 +63,13 @@ feature {NONE} -- Access
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- nino
|
||||
feature {NONE} -- standalone
|
||||
|
||||
nature_nino: STRING = "nino"
|
||||
nature_standalone: STRING = "standalone"
|
||||
|
||||
launch_nino (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
|
||||
launch_standalone (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
|
||||
local
|
||||
launcher: WSF_NINO_SERVICE_LAUNCHER
|
||||
launcher: WSF_STANDALONE_SERVICE_LAUNCHER
|
||||
do
|
||||
create launcher.make_and_launch (a_service, opts)
|
||||
end
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
<setting name="concurrency" value="thread"/>
|
||||
<library name="cgi" location="..\..\library\server\wsf\connector\cgi-safe.ecf" readonly="false"/>
|
||||
<library name="libfcgi" location="..\..\library\server\wsf\connector\libfcgi-safe.ecf" readonly="false"/>
|
||||
<library name="nino" location="..\..\library\server\wsf\connector\nino-safe.ecf" readonly="false"/>
|
||||
<library name="standalone" location="..\..\library\server\wsf\connector\standalone-safe.ecf" readonly="false"/>
|
||||
<cluster name="launcher" location=".\launcher\any\" recursive="true"/>
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
@@ -33,12 +32,6 @@
|
||||
<cluster name="launcher" location=".\launcher\default\" recursive="true"/>
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
<target name="debug_nino" extends="common">
|
||||
<root class="EWF_DEBUG_SERVER" feature="make_and_launch"/>
|
||||
<library name="default_nino" location="..\..\library\server\wsf\default\nino-safe.ecf"/>
|
||||
<cluster name="launcher" location=".\launcher\default\" recursive="true"/>
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
<target name="debug_cgi" extends="common">
|
||||
<root class="EWF_DEBUG_SERVER" feature="make_and_launch"/>
|
||||
<library name="default_cgi" location="..\..\library\server\wsf\default\cgi-safe.ecf" readonly="false"/>
|
||||
@@ -51,6 +44,6 @@
|
||||
<cluster name="launcher" location=".\launcher\default\" recursive="true"/>
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
<target name="debug" extends="debug_nino">
|
||||
<target name="debug" extends="debug_standalone">
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -24,8 +24,6 @@ feature -- Execution
|
||||
nature := launcher_nature
|
||||
if nature = Void or else nature = nature_standalone then
|
||||
launch_standalone (opts)
|
||||
elseif nature = nature_nino then
|
||||
launch_nino (opts)
|
||||
elseif nature = nature_cgi then
|
||||
launch_cgi (opts)
|
||||
elseif nature = nature_libfcgi then
|
||||
@@ -40,7 +38,7 @@ feature {NONE} -- Access
|
||||
|
||||
launcher_nature: detachable READABLE_STRING_8
|
||||
-- Initialize the launcher nature
|
||||
-- either cgi, libfcgi, or nino.
|
||||
-- either cgi, libfcgi, or standalone.
|
||||
--| We could extend with more connector if needed.
|
||||
--| and we could use WSF_DEFAULT_SERVICE_LAUNCHER to configure this at compilation time.
|
||||
local
|
||||
@@ -55,9 +53,6 @@ feature {NONE} -- Access
|
||||
if ext.same_string (nature_standalone) then
|
||||
Result := nature_standalone
|
||||
end
|
||||
if ext.same_string (nature_nino) then
|
||||
Result := nature_nino
|
||||
end
|
||||
if ext.same_string (nature_cgi) then
|
||||
Result := nature_cgi
|
||||
end
|
||||
@@ -68,7 +63,7 @@ feature {NONE} -- Access
|
||||
Result := nature_standalone
|
||||
end
|
||||
|
||||
feature {NONE} -- nino
|
||||
feature {NONE} -- Standalone
|
||||
|
||||
nature_standalone: STRING = "standalone"
|
||||
|
||||
@@ -79,17 +74,6 @@ feature {NONE} -- nino
|
||||
create launcher.make_and_launch (opts)
|
||||
end
|
||||
|
||||
feature {NONE} -- nino
|
||||
|
||||
nature_nino: STRING = "nino"
|
||||
|
||||
launch_nino (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
|
||||
local
|
||||
launcher: WSF_NINO_SERVICE_LAUNCHER [G]
|
||||
do
|
||||
create launcher.make_and_launch (opts)
|
||||
end
|
||||
|
||||
feature {NONE} -- cgi
|
||||
|
||||
nature_cgi: STRING = "cgi"
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
This example demonstrates the use of embedded Vision2 web browser component, and embedded EWF server (using nino).
|
||||
This example demonstrates the use of embedded Vision2 web browser component, and embedded EWF server (using standalone).
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option debug="true" warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="transitional" syntax="provisional">
|
||||
<debug name="nino" enabled="true"/>
|
||||
<assertions precondition="true" postcondition="true" invariant="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<setting name="concurrency" value="thread"/>
|
||||
@@ -20,11 +19,6 @@
|
||||
<library name="wsf_extension" location="..\..\library\server\wsf\wsf_extension-safe.ecf" readonly="true"/>
|
||||
<library name="wsf_router_context" location="..\..\library\server\wsf\wsf_router_context-safe.ecf" readonly="true"/>
|
||||
</target>
|
||||
<target name="filter_nino" extends="common">
|
||||
<root class="FILTER_SERVER" feature="make"/>
|
||||
<library name="default_nino" location="..\..\library\server\wsf\default\nino-safe.ecf" readonly="true"/>
|
||||
<cluster name="filter" location="src\" recursive="true"/>
|
||||
</target>
|
||||
<target name="filter_standalone" extends="common">
|
||||
<root class="FILTER_SERVER" feature="make"/>
|
||||
<setting name="concurrency" value="thread"/>
|
||||
@@ -36,6 +30,6 @@
|
||||
<library name="default_libfcgi" location="..\..\library\server\wsf\default\libfcgi-safe.ecf"/>
|
||||
<cluster name="filter" location="src\" recursive="true"/>
|
||||
</target>
|
||||
<target name="filter" extends="filter_nino">
|
||||
<target name="filter" extends="filter_standalone">
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -25,7 +25,7 @@ Note: <br/>
|
||||
|
||||
RESTBUCKS_SERVER
|
||||
----------------
|
||||
This class implement the main entry of our REST CRUD service, we are using a default connector (Nino Connector,
|
||||
This class implement the main entry of our REST CRUD service, we are using a default connector (Standalone Connector,
|
||||
using a WebServer written in Eiffel).
|
||||
We are inheriting from URI_TEMPLATE_ROUTED_SERVICE, this allows us to map our service contrat, as is shown in the previous
|
||||
table, the mapping is defined in the feature setup_router, this also show that the class ORDER_HANDLER will be encharge
|
||||
@@ -41,7 +41,7 @@ of to handle different type of request to the ORDER resource.
|
||||
URI_TEMPLATE_ROUTED_SERVICE
|
||||
|
||||
DEFAULT_SERVICE
|
||||
-- Here we are using a default connector using the default Nino Connector,
|
||||
-- Here we are using a default connector using the default Standalone Connector,
|
||||
-- but it's possible to use other connector (CGI or FCGI).
|
||||
|
||||
create
|
||||
|
||||
@@ -12,7 +12,6 @@ Currently, 4 connectors are available within EWF (but others are available outsi
|
||||
* CGI: the common CGI application (apache, iis, ...)
|
||||
* FastCGI: on any server supporting libfcgi handling (apache, iis, ...)
|
||||
* Standalone: a standalone Eiffel Web server, it can be run anywhere easily, and debug simply with EiffelStudio's debugger. It supports all concurrency modes, and require EiffelStudio >= 15.05.
|
||||
* Nino: similar to the "standalone" connectors, but lack good concurrency support.
|
||||
|
||||
Supporting a new connector is fairly simple, it just has to support the simple EWSGI specification which is really small. Then EWF will bring the power on top of it.
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="wsf" location="..\..\..\..\..\..\library\server\wsf\wsf-safe.ecf"/>
|
||||
<library name="default_nino" location="..\..\..\..\..\..\library\server\wsf\default\nino-safe.ecf"/>
|
||||
<library name="default_standalone" location="..\..\..\..\..\..\library\server\wsf\default\standalone-safe.ecf"/>
|
||||
<cluster name="src" location=".\"/>
|
||||
</target>
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ feature {NONE} -- Initialization
|
||||
--| Uncomment the following line, to be able to load options from the file ewf.ini
|
||||
-- create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI} service_options.make_from_file ("ewf.ini")
|
||||
|
||||
--| You can also uncomment the following line if you use the Nino connector
|
||||
--| You can also uncomment the following line if you use the Standalone connector
|
||||
--| so that the server listens on port 9999
|
||||
--| quite often the port 80 is already busy
|
||||
set_service_option ("port", 9999)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# For nino connector, use port 9999
|
||||
# For Standalone connector, use port 9999
|
||||
port=9999
|
||||
|
||||
#verbose=true
|
||||
|
||||
@@ -28,7 +28,7 @@ feature {NONE} -- Initialization
|
||||
--| Uncomment the following line, to be able to load options from the file ewf.ini
|
||||
create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI} service_options.make_from_file ("ewf.ini")
|
||||
|
||||
--| You can also uncomment the following line if you use the Nino connector
|
||||
--| You can also uncomment the following line if you use the Standalone connector
|
||||
--| so that the server listens on port 9999
|
||||
--| quite often the port 80 is already busy
|
||||
-- set_service_option ("port", 9999)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# For nino connector, use port 9999
|
||||
# For standalone connector, use port 9999
|
||||
port=9999
|
||||
|
||||
#verbose=true
|
||||
|
||||
@@ -22,7 +22,7 @@ feature {NONE} -- Initialization
|
||||
make
|
||||
-- Initialize Current
|
||||
do
|
||||
-- To use particular port number (as 9090) with Nino connector
|
||||
-- To use particular port number (as 9090) with Standalone connector
|
||||
-- Uncomment the following line
|
||||
set_service_option ("port", 9090)
|
||||
make_and_launch
|
||||
|
||||
@@ -20,10 +20,13 @@
|
||||
</target>
|
||||
<target name="upload_image_standalone" extends="upload_image_common">
|
||||
<root class="IMAGE_UPLOADER" feature="make"/>
|
||||
<setting name="concurrency" value="thread"/>
|
||||
<setting name="concurrency" value="scoop"/>
|
||||
<library name="default_standalone" location="..\..\library\server\wsf\default\standalone-safe.ecf" readonly="false" use_application_options="true"/>
|
||||
<cluster name="src" location="src\" recursive="true"/>
|
||||
</target>
|
||||
<target name="upload_image_standalone_st" extends="upload_image_standalone">
|
||||
<setting name="concurrency" value="none"/>
|
||||
</target>
|
||||
<target name="upload_image_libfcgi" extends="upload_image_common">
|
||||
<root class="IMAGE_UPLOADER" feature="make"/>
|
||||
<setting name="concurrency" value="none"/>
|
||||
|
||||
@@ -22,8 +22,8 @@ cgi-safe : C:\_dev\projects\ewf\ewf\library\server\ewsgi\connectors\cgi\cgi-safe
|
||||
cgi : C:\_dev\projects\ewf\ewf\library\server\ewsgi\connectors\cgi\cgi.ecf
|
||||
libfcgi-safe : C:\_dev\projects\ewf\ewf\library\server\ewsgi\connectors\libfcgi\libfcgi-safe.ecf
|
||||
libfcgi : C:\_dev\projects\ewf\ewf\library\server\ewsgi\connectors\libfcgi\libfcgi.ecf
|
||||
nino-safe : C:\_dev\projects\ewf\ewf\library\server\ewsgi\connectors\nino\nino-safe.ecf
|
||||
nino : C:\_dev\projects\ewf\ewf\library\server\ewsgi\connectors\nino\nino.ecf
|
||||
standalone-safe : C:\_dev\projects\ewf\ewf\library\server\ewsgi\connectors\standalone\standalone-safe.ecf
|
||||
standalone : C:\_dev\projects\ewf\ewf\library\server\ewsgi\connectors\standalone\standalone.ecf
|
||||
null-safe : C:\_dev\projects\ewf\ewf\library\server\ewsgi\connectors\null\null-safe.ecf
|
||||
null : C:\_dev\projects\ewf\ewf\library\server\ewsgi\connectors\null\null.ecf
|
||||
libfcgi-safe : C:\_dev\projects\ewf\ewf\library\server\libfcgi\libfcgi-safe.ecf
|
||||
@@ -43,15 +43,15 @@ cgi-safe : C:\_dev\projects\ewf\ewf\library\server\wsf\connector\cgi-safe.ecf
|
||||
cgi : C:\_dev\projects\ewf\ewf\library\server\wsf\connector\cgi.ecf
|
||||
libfcgi-safe : C:\_dev\projects\ewf\ewf\library\server\wsf\connector\libfcgi-safe.ecf
|
||||
libfcgi : C:\_dev\projects\ewf\ewf\library\server\wsf\connector\libfcgi.ecf
|
||||
nino-safe : C:\_dev\projects\ewf\ewf\library\server\wsf\connector\nino-safe.ecf
|
||||
nino : C:\_dev\projects\ewf\ewf\library\server\wsf\connector\nino.ecf
|
||||
standalone-safe : C:\_dev\projects\ewf\ewf\library\server\wsf\connector\standalone-safe.ecf
|
||||
standalone : C:\_dev\projects\ewf\ewf\library\server\wsf\connector\standalone.ecf
|
||||
openshift-safe : C:\_dev\projects\ewf\ewf\library\server\wsf\connector\openshift-safe.ecf
|
||||
cgi-safe : C:\_dev\projects\ewf\ewf\library\server\wsf\default\cgi-safe.ecf
|
||||
cgi : C:\_dev\projects\ewf\ewf\library\server\wsf\default\cgi.ecf
|
||||
libfcgi-safe : C:\_dev\projects\ewf\ewf\library\server\wsf\default\libfcgi-safe.ecf
|
||||
libfcgi : C:\_dev\projects\ewf\ewf\library\server\wsf\default\libfcgi.ecf
|
||||
nino-safe : C:\_dev\projects\ewf\ewf\library\server\wsf\default\nino-safe.ecf
|
||||
nino : C:\_dev\projects\ewf\ewf\library\server\wsf\default\nino.ecf
|
||||
standalone-safe : C:\_dev\projects\ewf\ewf\library\server\wsf\default\standalone-safe.ecf
|
||||
standalone : C:\_dev\projects\ewf\ewf\library\server\wsf\default\standalone.ecf
|
||||
openshift-safe : C:\_dev\projects\ewf\ewf\library\server\wsf\default\openshift-safe.ecf
|
||||
wsf_html-safe : C:\_dev\projects\ewf\ewf\library\server\wsf_html\wsf_html-safe.ecf
|
||||
wsf_html : C:\_dev\projects\ewf\ewf\library\server\wsf_html\wsf_html.ecf
|
||||
|
||||
@@ -8,7 +8,7 @@ class
|
||||
|
||||
inherit
|
||||
ANY
|
||||
|
||||
|
||||
SHARED_EXECUTION_ENVIRONMENT
|
||||
export
|
||||
{NONE} all
|
||||
@@ -21,7 +21,7 @@ feature {NONE} -- Initialization
|
||||
|
||||
make_and_launch
|
||||
local
|
||||
launcher: WSF_NINO_SERVICE_LAUNCHER [APPLICATION_EXECUTION]
|
||||
launcher: WSF_STANDALONE_SERVICE_LAUNCHER [APPLICATION_EXECUTION]
|
||||
opts: WSF_SERVICE_LAUNCHER_OPTIONS
|
||||
do
|
||||
create opts.make
|
||||
@@ -32,24 +32,22 @@ feature {NONE} -- Initialization
|
||||
launcher.launch
|
||||
end
|
||||
|
||||
on_launched (conn: WGI_CONNECTOR)
|
||||
on_launched (a_connector: WGI_STANDALONE_CONNECTOR [APPLICATION_EXECUTION])
|
||||
local
|
||||
e: EXECUTION_ENVIRONMENT
|
||||
cmd: STRING_32
|
||||
do
|
||||
if attached {WGI_NINO_CONNECTOR [APPLICATION_EXECUTION]} conn as nino then
|
||||
e := execution_environment
|
||||
create cmd.make (32)
|
||||
if attached e.item ("COMSPEC") as l_comspec then
|
||||
cmd.append (l_comspec)
|
||||
cmd.append ({STRING_32} " /C start ")
|
||||
end
|
||||
cmd.append ("http://localhost:")
|
||||
cmd.append_integer (nino.port)
|
||||
cmd.append_character ({CHARACTER_32} '/')
|
||||
|
||||
e.launch (cmd)
|
||||
e := execution_environment
|
||||
create cmd.make (32)
|
||||
if attached e.item ("COMSPEC") as l_comspec then
|
||||
cmd.append (l_comspec)
|
||||
cmd.append ({STRING_32} " /C start ")
|
||||
end
|
||||
cmd.append ("http://localhost:")
|
||||
cmd.append_integer (a_connector.port)
|
||||
cmd.append_character ({CHARACTER_32} '/')
|
||||
|
||||
e.launch (cmd)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -42,12 +42,12 @@ feature {NONE} -- Initialization
|
||||
m.set_title ("EWF::OpenID demo")
|
||||
create s.make_empty
|
||||
s.append ("<form action=%"" + req.script_url ("/openid") + "%" method=%"POST%">%N")
|
||||
s.append ("<strong>OpenID identifier</strong> <input type='text' name='openid_identifier' value='' size='60'/>")
|
||||
s.append ("<strong>Any OpenID identifier</strong> <input type='text' name='openid_identifier' value='' size='60'/>")
|
||||
s.append ("<input type='submit' name='op' value='sign with OpenID' />")
|
||||
s.append ("</form>%N")
|
||||
s.append ("<form action=%"" + req.script_url ("/openid") + "%" method=%"POST%">%N")
|
||||
s.append ("<strong>OpenID identifier</strong> <input type='text' name='openid_identifier' value='https://www.google.com/accounts/o8/id' size='60'/>")
|
||||
s.append ("<input type='submit' name='op' value='sign with Google' />")
|
||||
s.append ("<strong>OpenID identifier</strong> <input type='text' name='openid_identifier' value='https://me.yahoo.com/YOUR_YAHOO_USERNAME' size='60'/>")
|
||||
s.append ("<input type='submit' name='op' value='sign with Yahoo' />")
|
||||
s.append ("</form>%N")
|
||||
m.set_body (s)
|
||||
res.send (m)
|
||||
|
||||
@@ -1,23 +1,26 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-12-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-12-0 http://www.eiffel.com/developers/xml/configuration-1-12-0.xsd" name="demo" uuid="DC4D6549-D5F4-4E1A-959A-6BD536737A21" library_target="demo">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-15-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-15-0 http://www.eiffel.com/developers/xml/configuration-1-15-0.xsd" name="demo" uuid="DC4D6549-D5F4-4E1A-959A-6BD536737A21" library_target="demo">
|
||||
<target name="demo">
|
||||
<root class="APPLICATION" feature="make_and_launch"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
||||
<option warning="true" full_class_checking="false" is_attached_by_default="true" is_obsolete_routine_type="true" void_safety="all" syntax="transitional">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<setting name="concurrency" value="thread"/>
|
||||
<setting name="concurrency" value="scoop"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="ewsgi" location="..\..\..\..\server\ewsgi\ewsgi-safe.ecf" readonly="false"/>
|
||||
<library name="ewsgi_nino_connector" location="..\..\..\..\server\ewsgi\connectors\nino\nino-safe.ecf" readonly="false"/>
|
||||
<library name="ewsgi_standalone_connector" location="..\..\..\..\server\ewsgi\connectors\standalone\standalone-safe.ecf" readonly="false"/>
|
||||
<library name="http" location="..\..\..\..\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="openid" location="..\openid-safe.ecf" readonly="false"/>
|
||||
<library name="wsf" location="..\..\..\..\server\wsf\wsf-safe.ecf" readonly="false"/>
|
||||
<library name="wsf_nino_connector" location="..\..\..\..\server\wsf\connector\nino-safe.ecf" readonly="false"/>
|
||||
<library name="wsf_standalone_connector" location="..\..\..\..\server\wsf\connector\standalone-safe.ecf" readonly="false"/>
|
||||
<cluster name="src" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="demo_mt" extends="demo">
|
||||
<setting name="concurrency" value="thread"/>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<library name="http_auth" location="..\http_authorization-safe.ecf"/>
|
||||
<library name="encoders" location="..\..\..\..\text\encoder\encoder-safe.ecf"/>
|
||||
<library name="wsf" location="..\..\..\wsf\wsf-safe.ecf"/>
|
||||
<library name="default_nino" location="..\..\..\wsf\default\nino-safe.ecf"/>
|
||||
<library name="default_standalone" location="..\..\..\wsf\default\standalone-safe.ecf"/>
|
||||
<cluster name="src" location=".\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Overview
|
||||
The main goal of this library is to provide a common layer on top of many different connectors.
|
||||
A connector is a library used for the integration of Eiffel web server application with an underlying httpd server technology such as CGI, libFCGI, or even standalone Eiffel Web Nino (which is a httpd server written in Eiffel).
|
||||
A connector is a library used for the integration of Eiffel web server application with an underlying httpd server technology such as CGI, libFCGI, or even standalone Eiffel Web Standalone (which is a httpd server written in Eiffel).
|
||||
|
||||
Then one can build an Eiffel web service compliant with EWSGI specification, and thus with the same code (or almost), this could be compiled to run on any available connectors.
|
||||
|
||||
|
||||
@@ -18,21 +18,36 @@
|
||||
</condition>
|
||||
</library>
|
||||
<cluster name="network" location=".\network\">
|
||||
<cluster name="ssl_network" location="$|ssl\" recursive="true">
|
||||
<condition>
|
||||
<custom name="net_ssl_enabled" value="true"/>
|
||||
</condition>
|
||||
</cluster>
|
||||
<cluster name="network_until_16_05" location="$|until_16_05\">
|
||||
<file_rule>
|
||||
<exclude>/httpd_stream_socket_ext.e$</exclude>
|
||||
<condition>
|
||||
<version type="compiler" max="16.11.0.0"/>
|
||||
</condition>
|
||||
</cluster>
|
||||
<cluster name="network_from_16_11" location="$|from_16_11\">
|
||||
</file_rule>
|
||||
<cluster name="ssl_network" location="$|ssl\" recursive="true">
|
||||
<condition>
|
||||
<version type="compiler" min="16.11.0.0"/>
|
||||
<custom name="httpd_ssl_enabled" value="true"/>
|
||||
</condition>
|
||||
<file_rule>
|
||||
<exclude>/httpd_stream_ssl_socket_ext.e$</exclude>
|
||||
<condition>
|
||||
<version type="compiler" max="16.11.0.0"/>
|
||||
<custom name="httpd_ssl_enabled" value="true"/>
|
||||
</condition>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
</cluster>
|
||||
<cluster name="network_until_16_05" location=".\network\until_16_05\" recursive="false">
|
||||
<condition>
|
||||
<version type="compiler" max="16.11.0.0"/>
|
||||
</condition>
|
||||
<cluster name="ssl_network_until_16_05" location="$|ssl\" recursive="true">
|
||||
<condition>
|
||||
<custom name="httpd_ssl_enabled" value="true"/>
|
||||
<version type="compiler" max="16.11.0.0"/>
|
||||
</condition>
|
||||
</cluster>
|
||||
</cluster>
|
||||
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -19,19 +19,33 @@
|
||||
</condition>
|
||||
</library>
|
||||
<cluster name="network" location=".\network\">
|
||||
<cluster name="ssl_network" location="$|ssl\" recursive="true">
|
||||
<condition>
|
||||
<custom name="net_ssl_enabled" value="true"/>
|
||||
</condition>
|
||||
</cluster>
|
||||
<cluster name="network_until_16_05" location="$|until_16_05\">
|
||||
<file_rule>
|
||||
<exclude>/httpd_stream_socket_ext.e$</exclude>
|
||||
<condition>
|
||||
<version type="compiler" max="16.11.0.0"/>
|
||||
</condition>
|
||||
</cluster>
|
||||
<cluster name="network_from_16_11" location="$|from_16_11\">
|
||||
</file_rule>
|
||||
<cluster name="ssl_network" location="$|ssl\" recursive="true">
|
||||
<condition>
|
||||
<version type="compiler" min="16.11.0.0"/>
|
||||
<custom name="httpd_ssl_enabled" value="true"/>
|
||||
</condition>
|
||||
<file_rule>
|
||||
<exclude>/httpd_stream_ssl_socket_ext.e$</exclude>
|
||||
<condition>
|
||||
<version type="compiler" max="16.11.0.0"/>
|
||||
<custom name="httpd_ssl_enabled" value="true"/>
|
||||
</condition>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
</cluster>
|
||||
<cluster name="network_until_16_05" location=".\network\until_16_05\" recursive="false">
|
||||
<condition>
|
||||
<version type="compiler" max="16.11.0.0"/>
|
||||
</condition>
|
||||
<cluster name="ssl_network_until_16_05" location="$|ssl\" recursive="true">
|
||||
<condition>
|
||||
<custom name="httpd_ssl_enabled" value="true"/>
|
||||
<version type="compiler" max="16.11.0.0"/>
|
||||
</condition>
|
||||
</cluster>
|
||||
</cluster>
|
||||
|
||||
@@ -11,6 +11,16 @@
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<setting name="concurrency" value="scoop"/>
|
||||
<external_include location="$ECF_CONFIG_PATH/spec/include">
|
||||
<condition>
|
||||
<version type="compiler" min="16.11.0.0"/>
|
||||
</condition>
|
||||
</external_include>
|
||||
<external_include location="$ECF_CONFIG_PATH/spec/include_until_16_05">
|
||||
<condition>
|
||||
<version type="compiler" max="16.11.0.0"/>
|
||||
</condition>
|
||||
</external_include>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="net" location="$ISE_LIBRARY\library\net\net-safe.ecf"/>
|
||||
<library name="net_ssl" location="$ISE_LIBRARY\unstable\library\network\socket\netssl\net_ssl-safe.ecf">
|
||||
@@ -24,29 +34,12 @@
|
||||
</condition>
|
||||
</library>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
||||
<cluster name="network" location=".\network" recursive="false">
|
||||
<cluster name="ssl_network" location="$|ssl" recursive="true">
|
||||
<condition>
|
||||
<custom name="httpd_ssl_enabled" value="true"/>
|
||||
</condition>
|
||||
</cluster>
|
||||
<cluster name="network_until_16_05" location="$|until_16_05\">
|
||||
<condition>
|
||||
<version type="compiler" max="16.11.0.0"/>
|
||||
</condition>
|
||||
</cluster>
|
||||
<cluster name="network_from_16_11" location="$|from_16_11\">
|
||||
<condition>
|
||||
<version type="compiler" min="16.11.0.0"/>
|
||||
</condition>
|
||||
</cluster>
|
||||
</cluster>
|
||||
<cluster name="httpd_server" location=".\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/concurrency$</exclude>
|
||||
<exclude>/network$</exclude>
|
||||
<exclude>/no_ssl$</exclude>
|
||||
<exclude>/ssl$</exclude>
|
||||
<exclude>/network$</exclude>
|
||||
</file_rule>
|
||||
<cluster name="no_ssl" location="$|no_ssl\" recursive="true">
|
||||
<condition>
|
||||
@@ -74,5 +67,36 @@
|
||||
</condition>
|
||||
</cluster>
|
||||
</cluster>
|
||||
<cluster name="network" location=".\network\">
|
||||
<file_rule>
|
||||
<exclude>/httpd_stream_socket_ext.e$</exclude>
|
||||
<condition>
|
||||
<version type="compiler" max="16.11.0.0"/>
|
||||
</condition>
|
||||
</file_rule>
|
||||
<cluster name="ssl_network" location="$|ssl\" recursive="true">
|
||||
<condition>
|
||||
<custom name="httpd_ssl_enabled" value="true"/>
|
||||
</condition>
|
||||
<file_rule>
|
||||
<exclude>/httpd_stream_ssl_socket_ext.e$</exclude>
|
||||
<condition>
|
||||
<version type="compiler" max="16.11.0.0"/>
|
||||
<custom name="httpd_ssl_enabled" value="true"/>
|
||||
</condition>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
</cluster>
|
||||
<cluster name="network_until_16_05" location=".\network\until_16_05\" recursive="false">
|
||||
<condition>
|
||||
<version type="compiler" max="16.11.0.0"/>
|
||||
</condition>
|
||||
<cluster name="ssl_network_until_16_05" location="$|ssl\" recursive="true">
|
||||
<condition>
|
||||
<custom name="httpd_ssl_enabled" value="true"/>
|
||||
<version type="compiler" max="16.11.0.0"/>
|
||||
</condition>
|
||||
</cluster>
|
||||
</cluster>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -23,20 +23,34 @@
|
||||
</condition>
|
||||
</library>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
||||
<cluster name="network" location=".\network" recursive="false">
|
||||
<cluster name="ssl_network" location="$|ssl" recursive="true">
|
||||
<condition>
|
||||
<custom name="httpd_ssl_enabled" value="true"/>
|
||||
</condition>
|
||||
</cluster>
|
||||
<cluster name="network_until_16_05" location="$|until_16_05\">
|
||||
<cluster name="network" location=".\network\">
|
||||
<file_rule>
|
||||
<exclude>/httpd_stream_socket_ext.e$</exclude>
|
||||
<condition>
|
||||
<version type="compiler" max="16.11.0.0"/>
|
||||
</condition>
|
||||
</cluster>
|
||||
<cluster name="network_from_16_11" location="$|from_16_11\">
|
||||
</file_rule>
|
||||
<cluster name="ssl_network" location="$|ssl\" recursive="true">
|
||||
<condition>
|
||||
<version type="compiler" min="16.11.0.0"/>
|
||||
<custom name="httpd_ssl_enabled" value="true"/>
|
||||
</condition>
|
||||
<file_rule>
|
||||
<exclude>/httpd_stream_ssl_socket_ext.e$</exclude>
|
||||
<condition>
|
||||
<version type="compiler" max="16.11.0.0"/>
|
||||
<custom name="httpd_ssl_enabled" value="true"/>
|
||||
</condition>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
</cluster>
|
||||
<cluster name="network_until_16_05" location=".\network\until_16_05\" recursive="false">
|
||||
<condition>
|
||||
<version type="compiler" max="16.11.0.0"/>
|
||||
</condition>
|
||||
<cluster name="ssl_network_until_16_05" location="$|ssl\" recursive="true">
|
||||
<condition>
|
||||
<custom name="httpd_ssl_enabled" value="true"/>
|
||||
<version type="compiler" max="16.11.0.0"/>
|
||||
</condition>
|
||||
</cluster>
|
||||
</cluster>
|
||||
|
||||
@@ -154,7 +154,7 @@ feature -- Settings
|
||||
feature -- Status report
|
||||
|
||||
has_error: BOOLEAN
|
||||
-- Error occurred during `analyze_request_message'
|
||||
-- Error occurred during `get_request_header'
|
||||
|
||||
feature -- Status change
|
||||
|
||||
@@ -208,11 +208,21 @@ feature -- Execution
|
||||
is_connected: is_connected
|
||||
local
|
||||
l_socket: like client_socket
|
||||
l_remote_info: detachable like remote_info
|
||||
l_exit: BOOLEAN
|
||||
n,m: INTEGER
|
||||
do
|
||||
l_socket := client_socket
|
||||
l_socket.set_recv_timeout (socket_recv_timeout)
|
||||
|
||||
-- Compute remote info once for the persistent connection.
|
||||
create l_remote_info
|
||||
if attached l_socket.peer_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
|
||||
remote_info := l_remote_info
|
||||
|
||||
check
|
||||
socket_attached: l_socket /= Void
|
||||
socket_valid: l_socket.is_open_read and then l_socket.is_open_write
|
||||
@@ -252,9 +262,7 @@ feature -- Execution
|
||||
reuse_connection_when_possible: a_is_reusing_connection implies is_persistent_connection_supported
|
||||
no_error: not has_error
|
||||
local
|
||||
l_remote_info: detachable like remote_info
|
||||
l_socket: like client_socket
|
||||
l_is_ready: BOOLEAN
|
||||
do
|
||||
debug ("dbglog")
|
||||
if a_is_reusing_connection then
|
||||
@@ -276,50 +284,34 @@ feature -- Execution
|
||||
dbglog ("execute_request socket=" + l_socket.descriptor.out + " ENTER")
|
||||
end
|
||||
|
||||
if a_is_reusing_connection then
|
||||
--| set by default 5 seconds.
|
||||
l_socket.set_recv_timeout (keep_alive_timeout) -- in seconds!
|
||||
l_is_ready := socket_has_incoming_data (l_socket)
|
||||
else
|
||||
l_is_ready := True
|
||||
end
|
||||
-- Try to get request header.
|
||||
-- If the request is reusing persistent connection, use `keep_alive_timeout',
|
||||
-- otherwise `socket_recv_timeout'.
|
||||
get_request_header (l_socket, a_is_reusing_connection)
|
||||
|
||||
if l_is_ready then
|
||||
l_socket.set_recv_timeout (socket_recv_timeout) -- FIXME: return a 408 Request Timeout response ..
|
||||
create l_remote_info
|
||||
if attached l_socket.peer_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
|
||||
remote_info := l_remote_info
|
||||
end
|
||||
analyze_request_message (l_socket)
|
||||
|
||||
if has_error then
|
||||
-- check catch_bad_incoming_connection: False end
|
||||
if has_error then
|
||||
if a_is_reusing_connection and then request_header.is_empty then
|
||||
-- Close persistent connection, since no new connection occurred in the delay `keep_alive_timeout'.
|
||||
debug ("dbglog")
|
||||
dbglog ("execute_request socket=" + l_socket.descriptor.out + "} close persistent connection.")
|
||||
end
|
||||
else
|
||||
if is_verbose then
|
||||
log (request_header + "%NWARNING: invalid HTTP incoming request", warning_level)
|
||||
end
|
||||
process_bad_request (l_socket)
|
||||
is_persistent_connection_requested := False
|
||||
else
|
||||
if is_verbose then
|
||||
log (request_header, information_level)
|
||||
end
|
||||
process_request (l_socket)
|
||||
end
|
||||
else
|
||||
check is_reusing_connection: a_is_reusing_connection end
|
||||
-- Close persistent connection, since no new connection occurred in the delay `keep_alive_timeout'.
|
||||
is_persistent_connection_requested := False
|
||||
debug ("dbglog")
|
||||
dbglog ("execute_request socket=" + l_socket.descriptor.out + "} close persistent connection.")
|
||||
end
|
||||
end
|
||||
is_persistent_connection_requested := False
|
||||
else
|
||||
if is_verbose then
|
||||
log (request_header, information_level)
|
||||
end
|
||||
process_request (l_socket)
|
||||
end
|
||||
|
||||
debug ("dbglog")
|
||||
dbglog ("execute_request {" + l_socket.descriptor.out + "} LEAVE")
|
||||
end
|
||||
debug ("dbglog")
|
||||
dbglog ("execute_request {" + l_socket.descriptor.out + "} LEAVE")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -377,8 +369,11 @@ feature -- Request processing
|
||||
|
||||
feature -- Parsing
|
||||
|
||||
analyze_request_message (a_socket: HTTPD_STREAM_SOCKET)
|
||||
-- Analyze message extracted from `a_socket' as HTTP request
|
||||
get_request_header (a_socket: HTTPD_STREAM_SOCKET; a_is_reusing_connection: BOOLEAN)
|
||||
-- Analyze message extracted from `a_socket' as HTTP request.
|
||||
-- If `a_is_reusing_connection' is True, then first use
|
||||
-- Note: it reads from socket.
|
||||
-- Note: it updates `request_header' and `request_header_map', and eventually `is_persistent_connection_requested'.
|
||||
require
|
||||
input_readable: a_socket /= Void and then a_socket.is_open_read
|
||||
local
|
||||
@@ -391,76 +386,90 @@ feature -- Parsing
|
||||
do
|
||||
create txt.make (64)
|
||||
request_header := txt
|
||||
l_is_verbose := is_verbose
|
||||
|
||||
if
|
||||
not has_error and then
|
||||
a_socket.readable
|
||||
then
|
||||
if a_is_reusing_connection then
|
||||
a_socket.set_recv_timeout (keep_alive_timeout) -- in seconds!
|
||||
else
|
||||
a_socket.set_recv_timeout (socket_recv_timeout) -- FIXME: return a 408 Request Timeout response ..
|
||||
end
|
||||
|
||||
if
|
||||
attached next_line (a_socket) as l_request_line and then
|
||||
not l_request_line.is_empty
|
||||
not l_request_line.is_empty and then
|
||||
not has_error
|
||||
then
|
||||
txt.append (l_request_line)
|
||||
txt.append_character ('%N')
|
||||
analyze_request_line (l_request_line)
|
||||
|
||||
if not has_error then
|
||||
if a_is_reusing_connection then
|
||||
-- Restore normal recv timeout!
|
||||
a_socket.set_recv_timeout (socket_recv_timeout) -- FIXME: return a 408 Request Timeout response ..
|
||||
end
|
||||
from
|
||||
line := next_line (a_socket)
|
||||
until
|
||||
line = Void or end_of_stream or has_error
|
||||
loop
|
||||
n := line.count
|
||||
debug ("ew_standalone")
|
||||
if l_is_verbose then
|
||||
log (line, debug_level)
|
||||
end
|
||||
end
|
||||
pos := line.index_of (':', 1)
|
||||
if pos > 0 then
|
||||
k := line.substring (1, pos - 1)
|
||||
if line [pos + 1].is_space then
|
||||
pos := pos + 1
|
||||
end
|
||||
if line [n] = '%R' then
|
||||
n := n - 1
|
||||
end
|
||||
val := line.substring (pos + 1, n)
|
||||
request_header_map.put (val, k)
|
||||
end
|
||||
txt.append (line)
|
||||
txt.append_character ('%N')
|
||||
if line.is_empty or else line [1] = '%R' then
|
||||
end_of_stream := True
|
||||
else
|
||||
line := next_line (a_socket)
|
||||
end
|
||||
end
|
||||
-- Except for HTTP/1.0, persistent connection is the default.
|
||||
is_persistent_connection_requested := True
|
||||
if is_http_version_1_0 then
|
||||
is_persistent_connection_requested := attached request_header_map.item ("Connection") as l_connection and then
|
||||
l_connection.is_case_insensitive_equal_general ("keep-alive")
|
||||
else
|
||||
-- By default HTTP:1/1 support persistent connection.
|
||||
if attached request_header_map.item ("Connection") as l_connection then
|
||||
if l_connection.is_case_insensitive_equal_general ("close") then
|
||||
is_persistent_connection_requested := False
|
||||
end
|
||||
else
|
||||
is_persistent_connection_requested := True
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
report_error ("Bad header line (empty)")
|
||||
end
|
||||
else
|
||||
report_error ("Socket is not readable")
|
||||
end
|
||||
l_is_verbose := is_verbose
|
||||
if not has_error then
|
||||
from
|
||||
line := next_line (a_socket)
|
||||
until
|
||||
line = Void or end_of_stream or has_error
|
||||
loop
|
||||
n := line.count
|
||||
debug ("ew_standalone")
|
||||
if l_is_verbose then
|
||||
log (line, debug_level)
|
||||
end
|
||||
end
|
||||
pos := line.index_of (':', 1)
|
||||
if pos > 0 then
|
||||
k := line.substring (1, pos - 1)
|
||||
if line [pos + 1].is_space then
|
||||
pos := pos + 1
|
||||
end
|
||||
if line [n] = '%R' then
|
||||
n := n - 1
|
||||
end
|
||||
val := line.substring (pos + 1, n)
|
||||
request_header_map.put (val, k)
|
||||
end
|
||||
txt.append (line)
|
||||
txt.append_character ('%N')
|
||||
if line.is_empty or else line [1] = '%R' then
|
||||
end_of_stream := True
|
||||
else
|
||||
line := next_line (a_socket)
|
||||
end
|
||||
end
|
||||
-- Except for HTTP/1.0, persistent connection is the default.
|
||||
is_persistent_connection_requested := True
|
||||
if is_http_version_1_0 then
|
||||
is_persistent_connection_requested := attached request_header_map.item ("Connection") as l_connection and then
|
||||
l_connection.is_case_insensitive_equal_general ("keep-alive")
|
||||
else
|
||||
-- By default HTTP:1/1 support persistent connection.
|
||||
if attached request_header_map.item ("Connection") as l_connection then
|
||||
if l_connection.is_case_insensitive_equal_general ("close") then
|
||||
is_persistent_connection_requested := False
|
||||
end
|
||||
else
|
||||
is_persistent_connection_requested := True
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
analyze_request_line (line: STRING)
|
||||
-- Analyze `line' as a HTTP request line
|
||||
-- Analyze `line' as a HTTP request line.
|
||||
-- note: may update `has_error'.
|
||||
require
|
||||
valid_line: line /= Void and then not line.is_empty
|
||||
local
|
||||
@@ -488,28 +497,26 @@ feature -- Parsing
|
||||
|
||||
next_line (a_socket: HTTPD_STREAM_SOCKET): detachable STRING
|
||||
-- Next line fetched from `a_socket' is available.
|
||||
-- note: may update `has_error'.
|
||||
require
|
||||
not_has_error: not has_error or is_verbose
|
||||
not_has_error: not has_error
|
||||
is_readable: a_socket.is_open_read
|
||||
local
|
||||
retried: BOOLEAN
|
||||
do
|
||||
if retried then
|
||||
report_error ("Rescue in next_line")
|
||||
a_socket.close
|
||||
Result := Void
|
||||
elseif
|
||||
a_socket.readable and then
|
||||
socket_has_incoming_data (a_socket)
|
||||
then
|
||||
|
||||
a_socket.read_line_thread_aware
|
||||
elseif a_socket.readable then
|
||||
a_socket.read_line_noexception
|
||||
Result := a_socket.last_string
|
||||
-- Do no check `socket_ok' before socket operation,
|
||||
-- Do no check `was_error' before socket operation,
|
||||
-- otherwise it may be False, due to error during other socket operation in same thread.
|
||||
if not a_socket.socket_ok then
|
||||
if a_socket.was_error then
|
||||
report_error ("Socket error")
|
||||
if is_verbose then
|
||||
log (request_header +"%N" + Result + "%N## socket_ok=False! ##", debug_level)
|
||||
log (request_header +"%N" + Result + "%N## was_error=False! ##", debug_level)
|
||||
end
|
||||
end
|
||||
else
|
||||
@@ -520,6 +527,7 @@ feature -- Parsing
|
||||
end
|
||||
end
|
||||
rescue
|
||||
-- In case of network error exception (as EiffelNet reports error raising exception)
|
||||
retried := True
|
||||
retry
|
||||
end
|
||||
@@ -558,7 +566,9 @@ feature {NONE} -- Helpers
|
||||
a_socket.readable
|
||||
do
|
||||
-- FIXME: check if both are really needed.
|
||||
Result := a_socket.ready_for_reading and then a_socket.has_incoming_data
|
||||
-- Result := a_socket.ready_for_reading --and then a_socket.has_incoming_data
|
||||
-- Result := a_socket.has_incoming_data
|
||||
Result := True
|
||||
end
|
||||
|
||||
invariant
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
note
|
||||
description: "[
|
||||
Since 16.11, the EiffelNet socket interface has recv_timeout and send_timeout.
|
||||
]"
|
||||
|
||||
deferred class
|
||||
TCP_STREAM_SOCKET_EXT
|
||||
|
||||
end
|
||||
@@ -1,369 +1,235 @@
|
||||
note
|
||||
description: "[
|
||||
Summary description for {HTTPD_STREAM_SOCKET}
|
||||
that can be used for http or https connection.
|
||||
]"
|
||||
description: "Summary description for {HTTPD_STREAM_SOCKET}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
HTTPD_STREAM_SOCKET
|
||||
|
||||
inherit
|
||||
NETWORK_STREAM_SOCKET
|
||||
|
||||
HTTPD_STREAM_SOCKET_EXT
|
||||
|
||||
create
|
||||
make_server_by_address_and_port,
|
||||
make_server_by_port,
|
||||
make_client_by_address_and_port,
|
||||
make_client_by_port,
|
||||
make_from_separate,
|
||||
make_empty
|
||||
make, make_empty,
|
||||
make_client_by_port, make_client_by_address_and_port,
|
||||
make_server_by_port, make_server_by_address_and_port, make_loopback_server_by_port
|
||||
|
||||
create {HTTPD_STREAM_SOCKET}
|
||||
make
|
||||
create {NETWORK_STREAM_SOCKET}
|
||||
make_from_descriptor_and_address
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
feature -- Input
|
||||
|
||||
make_server_by_address_and_port (an_address: INET_ADDRESS; a_port: INTEGER)
|
||||
read_character_noexception
|
||||
-- Read a new character.
|
||||
-- Make result available in `last_character'.
|
||||
-- No exception raised!
|
||||
do
|
||||
create {TCP_STREAM_SOCKET} socket.make_server_by_address_and_port (an_address, a_port)
|
||||
read_to_managed_pointer_noexception (socket_buffer, 0, character_8_bytes)
|
||||
if bytes_read /= character_8_bytes then
|
||||
socket_error := "Peer closed connection"
|
||||
else
|
||||
last_character := socket_buffer.read_character (0)
|
||||
socket_error := Void
|
||||
end
|
||||
end
|
||||
|
||||
make_server_by_port (a_port: INTEGER)
|
||||
read_stream_noexception (nb_char: INTEGER)
|
||||
-- Read a string of at most `nb_char' characters.
|
||||
-- Make result available in `last_string'.
|
||||
local
|
||||
ext: C_STRING
|
||||
return_val: INTEGER
|
||||
do
|
||||
create {TCP_STREAM_SOCKET} socket.make_server_by_port (a_port)
|
||||
create ext.make_empty (nb_char + 1)
|
||||
return_val := c_read_stream_noexception (descriptor, nb_char, ext.item)
|
||||
bytes_read := return_val
|
||||
if return_val >= 0 then
|
||||
ext.set_count (return_val)
|
||||
last_string := ext.substring (1, return_val)
|
||||
else
|
||||
socket_error := "Peer error [0x" + return_val.to_hex_string + "]"
|
||||
last_string.wipe_out
|
||||
end
|
||||
end
|
||||
|
||||
make_client_by_address_and_port (an_address: INET_ADDRESS; a_port: INTEGER)
|
||||
read_to_managed_pointer_noexception (p: MANAGED_POINTER; start_pos, nb_bytes: INTEGER)
|
||||
-- Read at most `nb_bytes' bound bytes and make result
|
||||
-- available in `p' at position `start_pos'.
|
||||
-- No exception raised!
|
||||
do
|
||||
create {TCP_STREAM_SOCKET} socket.make_client_by_address_and_port (an_address, a_port)
|
||||
read_into_pointer_noexception (p.item, start_pos, nb_bytes)
|
||||
end
|
||||
|
||||
make_client_by_port (a_peer_port: INTEGER; a_peer_host: STRING)
|
||||
read_line_noexception
|
||||
-- Read a line of characters (ended by a new_line).
|
||||
-- No exception raised!
|
||||
local
|
||||
l_last_string: like last_string
|
||||
do
|
||||
create {TCP_STREAM_SOCKET} socket.make_client_by_port (a_peer_port, a_peer_host)
|
||||
create l_last_string.make (512)
|
||||
read_character_noexception
|
||||
from
|
||||
until
|
||||
last_character = '%N' or else was_error
|
||||
loop
|
||||
l_last_string.extend (last_character)
|
||||
read_character_noexception
|
||||
end
|
||||
last_string := l_last_string
|
||||
end
|
||||
|
||||
make_from_separate (s: separate HTTPD_STREAM_SOCKET)
|
||||
peek_stream_noexception (nb_char: INTEGER)
|
||||
-- Read a string of at most `nb_char' characters without removing the data from the queue.
|
||||
-- Make result available in last_string.
|
||||
-- No exception raised!
|
||||
require
|
||||
descriptor_available: s.descriptor_available
|
||||
readable: readable
|
||||
socket_exists: exists
|
||||
local
|
||||
ext: C_STRING
|
||||
retval: INTEGER
|
||||
l: like last_string
|
||||
do
|
||||
create {TCP_STREAM_SOCKET} socket.make_from_separate (s.socket)
|
||||
end
|
||||
|
||||
make_empty
|
||||
do
|
||||
create {TCP_STREAM_SOCKET} socket.make_empty
|
||||
end
|
||||
|
||||
retrieve_socket (s: HTTPD_STREAM_SOCKET): INTEGER
|
||||
do
|
||||
Result := s.socket.descriptor
|
||||
end
|
||||
|
||||
feature -- Change
|
||||
|
||||
set_timeout (n: INTEGER)
|
||||
-- Set timeout to `n' seconds.
|
||||
do
|
||||
if attached {NETWORK_STREAM_SOCKET} socket as l_socket then
|
||||
l_socket.set_timeout (n)
|
||||
create ext.make_empty (nb_char + 1)
|
||||
retval := c_recv_noexception (descriptor, ext.item, nb_char, c_peekmsg)
|
||||
if retval = 0 then
|
||||
last_string.wipe_out
|
||||
socket_error := Void
|
||||
elseif retval > 0 then
|
||||
ext.set_count (retval)
|
||||
l := last_string
|
||||
l.wipe_out
|
||||
l.grow (retval)
|
||||
l.set_count (retval)
|
||||
ext.read_substring_into (l, 1, retval)
|
||||
socket_error := Void
|
||||
else
|
||||
last_string.wipe_out
|
||||
socket_error := "Socket error (MSG_PEEK)"
|
||||
end
|
||||
ensure
|
||||
last_string_not_void: last_string /= Void
|
||||
end
|
||||
|
||||
set_connect_timeout (n: INTEGER)
|
||||
do
|
||||
if attached {NETWORK_STREAM_SOCKET} socket as l_socket then
|
||||
l_socket.set_connect_timeout (n)
|
||||
end
|
||||
end
|
||||
feature {NONE} -- Input
|
||||
|
||||
set_accept_timeout (n: INTEGER)
|
||||
do
|
||||
if attached {NETWORK_STREAM_SOCKET} socket as l_socket then
|
||||
l_socket.set_accept_timeout (n)
|
||||
end
|
||||
end
|
||||
|
||||
set_recv_timeout (a_timeout_seconds: INTEGER)
|
||||
-- Set the receive timeout in seconds on Current socket.
|
||||
do
|
||||
if attached {TCP_STREAM_SOCKET} socket as l_socket then
|
||||
l_socket.set_recv_timeout (a_timeout_seconds)
|
||||
end
|
||||
end
|
||||
|
||||
set_send_timeout (a_timeout_seconds: INTEGER)
|
||||
-- Set the send timeout in seconds on Current socket.
|
||||
do
|
||||
if attached {TCP_STREAM_SOCKET} socket as l_socket then
|
||||
l_socket.set_send_timeout (a_timeout_seconds)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
last_string: STRING
|
||||
do
|
||||
Result := socket.last_string
|
||||
end
|
||||
|
||||
last_character: CHARACTER
|
||||
do
|
||||
Result := socket.last_character
|
||||
end
|
||||
|
||||
peer_address: detachable NETWORK_SOCKET_ADDRESS
|
||||
-- Peer address of socket
|
||||
do
|
||||
if attached {NETWORK_SOCKET_ADDRESS} socket.peer_address as l_peer_address then
|
||||
Result := l_peer_address
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Input
|
||||
|
||||
read_line_thread_aware
|
||||
do
|
||||
socket.read_line_thread_aware
|
||||
end
|
||||
|
||||
read_stream_thread_aware (nb: INTEGER)
|
||||
do
|
||||
socket.read_stream_thread_aware (nb)
|
||||
end
|
||||
|
||||
read_stream (nb: INTEGER)
|
||||
do
|
||||
socket.read_stream (nb)
|
||||
end
|
||||
|
||||
read_character
|
||||
do
|
||||
socket.read_character
|
||||
end
|
||||
|
||||
peek_stream (nb_char: INTEGER)
|
||||
read_into_pointer_noexception (p: POINTER; start_pos, nb_bytes: INTEGER_32)
|
||||
-- Read at most `nb_bytes' bound bytes and make result
|
||||
-- available in `p' at position `start_pos'.
|
||||
-- No exception raised!
|
||||
require
|
||||
nb_char_positive: nb_char > 0
|
||||
p_not_void: p /= default_pointer
|
||||
nb_bytes_non_negative: nb_bytes >= 0
|
||||
is_readable: readable
|
||||
local
|
||||
l_read: INTEGER_32
|
||||
l_last_read: INTEGER_32
|
||||
do
|
||||
if attached {TCP_STREAM_SOCKET} socket as l_socket then
|
||||
l_socket.peek_stream (nb_char)
|
||||
from
|
||||
l_last_read := 1
|
||||
until
|
||||
l_read = nb_bytes or l_last_read <= 0
|
||||
loop
|
||||
l_last_read := c_read_stream_noexception (descriptor, nb_bytes - l_read, p + start_pos + l_read)
|
||||
if l_last_read >= 0 then
|
||||
l_read := l_read + l_last_read
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
bytes_read: INTEGER
|
||||
do
|
||||
Result := socket.bytes_read
|
||||
bytes_read := l_read
|
||||
ensure
|
||||
bytes_read_updated: 0 <= bytes_read and bytes_read <= nb_bytes
|
||||
end
|
||||
|
||||
feature -- Output
|
||||
|
||||
send_message (a_msg: STRING)
|
||||
bytes_sent: INTEGER
|
||||
-- Last number of bytes sent by `put_managed_pointer_noexception' (i.e `put_pointer_content_noexception').
|
||||
|
||||
put_managed_pointer_noexception (p: MANAGED_POINTER; start_pos, nb_bytes: INTEGER_32)
|
||||
-- Put data of length `nb_bytes' pointed by `start_pos' index in `p' at
|
||||
-- current position.
|
||||
-- Update `bytes_sent'.
|
||||
-- No exception raised!
|
||||
require
|
||||
p_not_void: p /= Void
|
||||
p_large_enough: p.count >= nb_bytes + start_pos
|
||||
nb_bytes_non_negative: nb_bytes >= 0
|
||||
extendible: extendible
|
||||
do
|
||||
put_string (a_msg)
|
||||
put_pointer_content_noexception (p.item, start_pos, nb_bytes)
|
||||
end
|
||||
|
||||
put_pointer_content_noexception (a_pointer: POINTER; a_offset, a_byte_count: INTEGER)
|
||||
-- Write `a_byte_count' bytes to the socket.
|
||||
-- The data is taken from the memory area pointed to by `a_pointer', at offset `a_offset'.
|
||||
-- Update `bytes_sent'.
|
||||
-- No exception raised!
|
||||
require
|
||||
pointer_not_void: a_pointer /= default_pointer
|
||||
byte_count_non_negative: a_byte_count >= 0
|
||||
extendible: extendible
|
||||
local
|
||||
l_sent: INTEGER_32
|
||||
l_last_sent: INTEGER_32
|
||||
do
|
||||
from
|
||||
l_last_sent := 1
|
||||
until
|
||||
l_sent = a_byte_count or l_last_sent <= 0
|
||||
loop
|
||||
l_last_sent := c_put_stream_noexception (descriptor, a_pointer + a_offset + l_sent, a_byte_count - l_sent)
|
||||
if l_last_sent >= 0 then
|
||||
l_sent := l_sent + l_last_sent
|
||||
elseif l_sent < a_byte_count then
|
||||
socket_error := "No all bytes sent!"
|
||||
end
|
||||
end
|
||||
bytes_sent := l_sent
|
||||
ensure
|
||||
bytes_sent_updated: not was_error implies (0 <= bytes_sent and bytes_sent <= a_byte_count)
|
||||
end
|
||||
|
||||
put_character_noexception (c: CHARACTER)
|
||||
-- Write character `c' to socket.
|
||||
do
|
||||
socket_buffer.put_character (c, 0)
|
||||
put_managed_pointer_noexception (socket_buffer, 0, character_8_bytes)
|
||||
end
|
||||
|
||||
put_readable_string_8_noexception (s: READABLE_STRING_8)
|
||||
-- Write readable string `s' to socket.
|
||||
-- No exception raised!
|
||||
local
|
||||
ext: C_STRING
|
||||
do
|
||||
create ext.make (s)
|
||||
put_managed_pointer_noexception (ext.managed_data, 0, s.count)
|
||||
end
|
||||
|
||||
put_readable_string_8 (s: READABLE_STRING_8)
|
||||
-- Write readable string `s' to socket.
|
||||
local
|
||||
ext: C_STRING
|
||||
do
|
||||
if attached {TCP_STREAM_SOCKET} socket as l_tcp_stream_socket then
|
||||
l_tcp_stream_socket.put_readable_string_8 (s)
|
||||
else
|
||||
put_string (s)
|
||||
end
|
||||
create ext.make (s)
|
||||
put_managed_pointer (ext.managed_data, 0, s.count)
|
||||
end
|
||||
|
||||
put_string (s: STRING)
|
||||
do
|
||||
socket.put_string (s)
|
||||
end
|
||||
|
||||
put_character (c: CHARACTER)
|
||||
do
|
||||
socket.put_character (c)
|
||||
end
|
||||
|
||||
feature -- Status Report
|
||||
|
||||
descriptor_available: BOOLEAN
|
||||
-- Is descriptor available?
|
||||
do
|
||||
Result := socket.descriptor_available
|
||||
end
|
||||
|
||||
descriptor: INTEGER
|
||||
do
|
||||
Result := socket.descriptor
|
||||
end
|
||||
|
||||
port: INTEGER
|
||||
do
|
||||
if attached {TCP_STREAM_SOCKET} socket as l_socket then
|
||||
Result := l_socket.port
|
||||
end
|
||||
end
|
||||
|
||||
exists: BOOLEAN
|
||||
do
|
||||
Result := socket.exists
|
||||
end
|
||||
|
||||
is_blocking: BOOLEAN
|
||||
do
|
||||
Result := socket.is_blocking
|
||||
end
|
||||
|
||||
is_bound: BOOLEAN
|
||||
do
|
||||
if attached {TCP_STREAM_SOCKET} socket as l_socket then
|
||||
Result := l_socket.is_bound
|
||||
end
|
||||
end
|
||||
|
||||
is_connected: BOOLEAN
|
||||
do
|
||||
if attached {TCP_STREAM_SOCKET} socket as l_socket then
|
||||
Result := l_socket.is_connected
|
||||
end
|
||||
end
|
||||
|
||||
is_created: BOOLEAN
|
||||
do
|
||||
if attached {NETWORK_SOCKET} socket as l_socket then
|
||||
Result := l_socket.is_created
|
||||
end
|
||||
end
|
||||
|
||||
socket_ok: BOOLEAN
|
||||
do
|
||||
Result := socket.socket_ok
|
||||
end
|
||||
|
||||
is_open_read: BOOLEAN
|
||||
do
|
||||
Result := socket.is_open_read
|
||||
end
|
||||
|
||||
is_open_write: BOOLEAN
|
||||
do
|
||||
Result := socket.is_open_write
|
||||
end
|
||||
|
||||
is_closed: BOOLEAN
|
||||
do
|
||||
Result := socket.is_closed
|
||||
end
|
||||
|
||||
is_readable: BOOLEAN
|
||||
do
|
||||
Result := socket.is_readable
|
||||
end
|
||||
|
||||
cleanup
|
||||
do
|
||||
socket.cleanup
|
||||
end
|
||||
|
||||
ready_for_writing: BOOLEAN
|
||||
do
|
||||
if attached {TCP_STREAM_SOCKET} socket as l_socket then
|
||||
Result := l_socket.ready_for_writing
|
||||
end
|
||||
end
|
||||
|
||||
connect
|
||||
do
|
||||
socket.connect
|
||||
end
|
||||
|
||||
close
|
||||
do
|
||||
socket.close
|
||||
end
|
||||
|
||||
listen (a_queue: INTEGER)
|
||||
do
|
||||
socket.listen (a_queue)
|
||||
end
|
||||
|
||||
accept
|
||||
do
|
||||
socket.accept
|
||||
end
|
||||
|
||||
accept_to (other: separate HTTPD_STREAM_SOCKET)
|
||||
-- Accept a new connection on listen socket.
|
||||
-- Socket of accepted connection is available in `other'.
|
||||
do
|
||||
if
|
||||
attached {NETWORK_STREAM_SOCKET} socket as l_socket and then
|
||||
attached {separate NETWORK_STREAM_SOCKET} other.socket as l_other_socket
|
||||
then
|
||||
l_socket.accept_to (l_other_socket)
|
||||
end
|
||||
end
|
||||
|
||||
set_blocking
|
||||
do
|
||||
socket.set_blocking
|
||||
end
|
||||
|
||||
set_non_blocking
|
||||
do
|
||||
socket.set_non_blocking
|
||||
end
|
||||
|
||||
readable: BOOLEAN
|
||||
do
|
||||
Result := socket.readable
|
||||
end
|
||||
feature -- Status report
|
||||
|
||||
has_incoming_data: BOOLEAN
|
||||
-- Check if Current has available data to be read.
|
||||
-- note: no data will not be removed from the queue.
|
||||
require
|
||||
socket_exists: exists
|
||||
do
|
||||
if attached {TCP_STREAM_SOCKET} socket as l_socket then
|
||||
Result := l_socket.has_incoming_data
|
||||
end
|
||||
peek_stream_noexception (1)
|
||||
Result := last_string.count = 1
|
||||
end
|
||||
|
||||
ready_for_reading: BOOLEAN
|
||||
do
|
||||
if attached {TCP_STREAM_SOCKET} socket as l_socket then
|
||||
Result := l_socket.ready_for_reading
|
||||
end
|
||||
end
|
||||
|
||||
try_ready_for_reading: BOOLEAN
|
||||
do
|
||||
if attached {TCP_STREAM_SOCKET} socket as l_socket then
|
||||
Result := l_socket.try_ready_for_reading
|
||||
end
|
||||
end
|
||||
|
||||
accepted: detachable HTTPD_STREAM_SOCKET
|
||||
do
|
||||
if attached {NETWORK_STREAM_SOCKET} socket.accepted as l_accepted then
|
||||
create Result.make (l_accepted)
|
||||
end
|
||||
end
|
||||
|
||||
feature {HTTPD_STREAM_SOCKET} -- Implementation
|
||||
|
||||
make (a_socket: STREAM_SOCKET)
|
||||
do
|
||||
socket := a_socket
|
||||
end
|
||||
|
||||
socket: STREAM_SOCKET
|
||||
|
||||
network_stream_socket: detachable NETWORK_STREAM_SOCKET
|
||||
do
|
||||
if attached {NETWORK_STREAM_SOCKET} socket as s then
|
||||
Result := s
|
||||
end
|
||||
end
|
||||
|
||||
;note
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
@@ -373,4 +239,5 @@ feature {HTTPD_STREAM_SOCKET} -- Implementation
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
|
||||
end
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
note
|
||||
description: "[
|
||||
Extension to HTTPD_STREAM_SOCKET to support backward compatibility.
|
||||
|
||||
TO BE REMOVED IN THE FUTURE, WHEN 16.05 IS OLD.
|
||||
]"
|
||||
|
||||
deferred class
|
||||
HTTPD_STREAM_SOCKET_EXT
|
||||
|
||||
feature {NONE} -- No-Exception network operation
|
||||
|
||||
end
|
||||
@@ -1,8 +1,5 @@
|
||||
note
|
||||
description: "[
|
||||
Summary description for {HTTPD_STREAM_SSL_SOCKET}
|
||||
that can be used for http or https connection.
|
||||
]"
|
||||
description: "SSL tcp stream socket."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
@@ -11,159 +8,142 @@ class
|
||||
|
||||
inherit
|
||||
HTTPD_STREAM_SOCKET
|
||||
undefine
|
||||
make_empty, make_from_descriptor_and_address,
|
||||
error_number,
|
||||
readstream, read_stream,
|
||||
read_into_pointer,
|
||||
read_to_managed_pointer,
|
||||
put_pointer_content,
|
||||
write, send,
|
||||
close_socket,
|
||||
connect, shutdown,
|
||||
do_accept
|
||||
redefine
|
||||
port,
|
||||
is_bound,
|
||||
ready_for_writing,
|
||||
ready_for_reading,
|
||||
try_ready_for_reading,
|
||||
put_readable_string_8,
|
||||
make_empty
|
||||
put_managed_pointer,
|
||||
read_stream_noexception,
|
||||
read_into_pointer_noexception,
|
||||
put_pointer_content_noexception
|
||||
end
|
||||
|
||||
SSL_NETWORK_STREAM_SOCKET
|
||||
redefine
|
||||
put_managed_pointer -- Redefine to allow support of compiler before 16.11.
|
||||
end
|
||||
|
||||
HTTPD_STREAM_SSL_SOCKET_EXT
|
||||
|
||||
create
|
||||
make_ssl_server_by_address_and_port, make_ssl_server_by_port,
|
||||
make_server_by_address_and_port, make_server_by_port,
|
||||
make_ssl_client_by_address_and_port, make_ssl_client_by_port,
|
||||
make_client_by_address_and_port, make_client_by_port,
|
||||
make_empty
|
||||
make, make_empty,
|
||||
make_client_by_port, make_client_by_address_and_port,
|
||||
make_server_by_port, make_server_by_address_and_port, make_loopback_server_by_port
|
||||
|
||||
create {HTTPD_STREAM_SOCKET}
|
||||
make
|
||||
create {SSL_NETWORK_STREAM_SOCKET}
|
||||
make_from_descriptor_and_address
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
feature -- Input
|
||||
|
||||
make_ssl_server_by_address_and_port (an_address: INET_ADDRESS; a_port: INTEGER; a_ssl_protocol: NATURAL; a_crt_fn, a_key_fn: detachable READABLE_STRING_GENERAL)
|
||||
read_stream_noexception (nb_char: INTEGER)
|
||||
-- Read a string of at most `nb_char' characters.
|
||||
-- Make result available in `last_string'.
|
||||
local
|
||||
l_socket: SSL_TCP_STREAM_SOCKET
|
||||
ext: C_STRING
|
||||
return_val: INTEGER
|
||||
do
|
||||
create l_socket.make_server_by_address_and_port (an_address, a_port)
|
||||
l_socket.set_tls_protocol (a_ssl_protocol)
|
||||
socket := l_socket
|
||||
set_certificates (a_crt_fn, a_key_fn)
|
||||
if
|
||||
attached context as l_context and then
|
||||
attached l_context.last_ssl as l_ssl
|
||||
then
|
||||
create ext.make_empty (nb_char + 1)
|
||||
return_val := l_ssl.read (ext.item , nb_char)
|
||||
bytes_read := return_val
|
||||
if return_val >= 0 then
|
||||
ext.set_count (return_val)
|
||||
last_string := ext.substring (1, return_val)
|
||||
else
|
||||
socket_error := "Peer error [0x" + return_val.to_hex_string + "]"
|
||||
last_string.wipe_out
|
||||
end
|
||||
else
|
||||
check has_context: False end
|
||||
end
|
||||
end
|
||||
|
||||
make_ssl_server_by_port (a_port: INTEGER; a_ssl_protocol: NATURAL; a_crt_fn, a_key_fn: detachable READABLE_STRING_GENERAL)
|
||||
local
|
||||
l_socket: SSL_TCP_STREAM_SOCKET
|
||||
do
|
||||
create l_socket.make_server_by_port (a_port)
|
||||
l_socket.set_tls_protocol (a_ssl_protocol)
|
||||
socket := l_socket
|
||||
set_certificates (a_crt_fn, a_key_fn)
|
||||
end
|
||||
feature {NONE} -- Input
|
||||
|
||||
make_ssl_client_by_address_and_port (an_address: INET_ADDRESS; a_port: INTEGER; a_ssl_protocol: NATURAL; a_crt_fn, a_key_fn: detachable READABLE_STRING_GENERAL)
|
||||
read_into_pointer_noexception (p: POINTER; start_pos, nb_bytes: INTEGER_32)
|
||||
-- Read at most `nb_bytes' bound bytes and make result
|
||||
-- available in `p' at position `start_pos'.
|
||||
-- No exception raised!
|
||||
local
|
||||
l_socket: SSL_TCP_STREAM_SOCKET
|
||||
l_read: INTEGER
|
||||
l_last_read: INTEGER
|
||||
do
|
||||
create l_socket.make_client_by_address_and_port (an_address, a_port)
|
||||
l_socket.set_tls_protocol (a_ssl_protocol)
|
||||
socket := l_socket
|
||||
set_certificates (a_crt_fn, a_key_fn)
|
||||
end
|
||||
|
||||
make_ssl_client_by_port (a_peer_port: INTEGER; a_peer_host: STRING; a_ssl_protocol: NATURAL; a_crt_fn, a_key_fn: detachable READABLE_STRING_GENERAL)
|
||||
local
|
||||
l_socket: SSL_TCP_STREAM_SOCKET
|
||||
do
|
||||
create l_socket.make_client_by_port (a_peer_port, a_peer_host)
|
||||
l_socket.set_tls_protocol (a_ssl_protocol)
|
||||
socket := l_socket
|
||||
set_certificates (a_crt_fn, a_key_fn)
|
||||
end
|
||||
|
||||
make_empty
|
||||
-- <Precursor>.
|
||||
do
|
||||
create {SSL_TCP_STREAM_SOCKET} socket.make_empty
|
||||
if
|
||||
attached context as l_context and then
|
||||
attached l_context.last_ssl as l_ssl
|
||||
then
|
||||
from
|
||||
l_last_read := 1
|
||||
until
|
||||
l_read = nb_bytes or l_last_read <= 0
|
||||
loop
|
||||
l_last_read := l_ssl.read (p + start_pos + l_read, nb_bytes - l_read)
|
||||
if l_last_read >= 0 then
|
||||
l_read := l_read + l_last_read
|
||||
end
|
||||
end
|
||||
bytes_read := l_read
|
||||
else
|
||||
check has_context: False end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Output
|
||||
|
||||
put_readable_string_8 (s: READABLE_STRING_8)
|
||||
-- <Precursor>
|
||||
put_managed_pointer (p: MANAGED_POINTER; start_pos, nb_bytes: INTEGER)
|
||||
-- Put data of length `nb_bytes' pointed by `start_pos' index in `p' at
|
||||
-- current position.
|
||||
do
|
||||
if attached {SSL_TCP_STREAM_SOCKET} socket as l_ssl_socket then
|
||||
l_ssl_socket.put_readable_string_8 (s)
|
||||
else
|
||||
Precursor (s)
|
||||
end
|
||||
Precursor {HTTPD_STREAM_SOCKET} (p, start_pos, nb_bytes)
|
||||
end
|
||||
|
||||
feature -- Status Report
|
||||
|
||||
port: INTEGER
|
||||
-- <Precursor>
|
||||
put_pointer_content_noexception (a_pointer: POINTER; a_offset, a_byte_count: INTEGER)
|
||||
-- Write `a_byte_count' bytes to the socket.
|
||||
-- The data is taken from the memory area pointed to by `a_pointer', at offset `a_offset'.
|
||||
-- Update `bytes_sent'.
|
||||
-- No exception raised!
|
||||
local
|
||||
l_bytes_sent: INTEGER
|
||||
do
|
||||
if attached {SSL_TCP_STREAM_SOCKET} socket as l_ssl_socket then
|
||||
Result := l_ssl_socket.port
|
||||
else
|
||||
Result := Precursor
|
||||
end
|
||||
end
|
||||
|
||||
is_bound: BOOLEAN
|
||||
-- <Precursor>
|
||||
do
|
||||
if attached {SSL_TCP_STREAM_SOCKET} socket as l_ssl_socket then
|
||||
Result := l_ssl_socket.is_bound
|
||||
else
|
||||
Result := Precursor
|
||||
end
|
||||
end
|
||||
|
||||
ready_for_writing: BOOLEAN
|
||||
-- <Precursor>
|
||||
do
|
||||
if attached {SSL_TCP_STREAM_SOCKET} socket as l_ssl_socket then
|
||||
Result := l_ssl_socket.ready_for_writing
|
||||
else
|
||||
Result := Precursor
|
||||
end
|
||||
end
|
||||
|
||||
ready_for_reading: BOOLEAN
|
||||
-- <Precursor>
|
||||
do
|
||||
if attached {SSL_TCP_STREAM_SOCKET} socket as l_ssl_socket then
|
||||
Result := l_ssl_socket.ready_for_reading
|
||||
else
|
||||
Result := Precursor
|
||||
end
|
||||
end
|
||||
|
||||
try_ready_for_reading: BOOLEAN
|
||||
do
|
||||
if attached {SSL_TCP_STREAM_SOCKET} socket as l_socket then
|
||||
Result := l_socket.try_ready_for_reading
|
||||
else
|
||||
Result := Precursor
|
||||
end
|
||||
end
|
||||
|
||||
feature {HTTPD_STREAM_SOCKET} -- Implementation
|
||||
|
||||
set_certificates (a_crt_filename, a_key_filename: detachable READABLE_STRING_GENERAL)
|
||||
do
|
||||
if attached {SSL_NETWORK_STREAM_SOCKET} socket as l_socket then
|
||||
if a_crt_filename /= Void then
|
||||
l_socket.set_certificate_file_name (a_crt_filename)
|
||||
end
|
||||
if a_key_filename /= Void then
|
||||
l_socket.set_key_file_name (a_key_filename)
|
||||
if
|
||||
attached context as l_context and then
|
||||
attached l_context.last_ssl as l_ssl
|
||||
then
|
||||
l_bytes_sent := ssl_write (l_ssl, a_pointer + a_offset, a_byte_count)
|
||||
if l_bytes_sent < a_byte_count then
|
||||
socket_error := "No all bytes sent!"
|
||||
end
|
||||
bytes_sent := l_bytes_sent
|
||||
else
|
||||
check has_last_ssl: False end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_certificate_filenames (a_crt_filename, a_key_filename: detachable READABLE_STRING_GENERAL)
|
||||
do
|
||||
if a_crt_filename /= Void then
|
||||
set_certificate_file_name (a_crt_filename)
|
||||
end
|
||||
if a_key_filename /= Void then
|
||||
set_key_file_name (a_key_filename)
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
|
||||
end
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
note
|
||||
description: "[
|
||||
Extension to HTTPD_STREAM_SOCKET to support backward compatibility.
|
||||
|
||||
TO BE REMOVED IN THE FUTURE, WHEN 16.05 IS OLD.
|
||||
]"
|
||||
|
||||
deferred class
|
||||
HTTPD_STREAM_SSL_SOCKET_EXT
|
||||
|
||||
feature {NONE} -- SSL bridge
|
||||
|
||||
ssl_write (a_ssl: SSL; a_pointer: POINTER; a_byte_count: INTEGER): INTEGER
|
||||
do
|
||||
Result := a_ssl.write (a_pointer, a_byte_count)
|
||||
if a_ssl.was_error then
|
||||
if Result >= 0 then
|
||||
Result := -1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,73 +0,0 @@
|
||||
note
|
||||
description: "SSL tcp stream socket."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
SSL_TCP_STREAM_SOCKET
|
||||
|
||||
inherit
|
||||
|
||||
SSL_NETWORK_STREAM_SOCKET
|
||||
|
||||
create
|
||||
make_server_by_address_and_port, make_server_by_port,
|
||||
make_client_by_address_and_port, make_client_by_port,
|
||||
make_empty
|
||||
|
||||
create {SSL_NETWORK_STREAM_SOCKET}
|
||||
make_from_descriptor_and_address
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make_server_by_address_and_port (an_address: INET_ADDRESS; a_port: INTEGER)
|
||||
-- Create server socket on `an_address' and `a_port'.
|
||||
require
|
||||
valid_port: a_port >= 0
|
||||
do
|
||||
make
|
||||
create address.make_from_address_and_port (an_address, a_port)
|
||||
bind
|
||||
end
|
||||
|
||||
feature -- Basic operation
|
||||
|
||||
send_message (a_msg: STRING)
|
||||
do
|
||||
put_string (a_msg)
|
||||
end
|
||||
|
||||
feature -- Output
|
||||
|
||||
put_readable_string_8 (s: READABLE_STRING_8)
|
||||
-- Write readable string `s' to socket.
|
||||
local
|
||||
ext: C_STRING
|
||||
do
|
||||
create ext.make (s)
|
||||
put_managed_pointer (ext.managed_data, 0, s.count)
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
try_ready_for_reading: BOOLEAN
|
||||
-- Is data available for reading from the socket right now?
|
||||
require
|
||||
socket_exists: exists
|
||||
local
|
||||
retval: INTEGER
|
||||
do
|
||||
retval := c_select_poll_with_timeout (descriptor, True, 0)
|
||||
Result := (retval > 0)
|
||||
end
|
||||
|
||||
feature {NONE}-- Implementation
|
||||
|
||||
|
||||
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
|
||||
end
|
||||
@@ -1,153 +0,0 @@
|
||||
note
|
||||
description: "Summary description for {TCP_STREAM_SOCKET}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
TCP_STREAM_SOCKET
|
||||
|
||||
inherit
|
||||
NETWORK_STREAM_SOCKET
|
||||
redefine
|
||||
make
|
||||
end
|
||||
|
||||
TCP_STREAM_SOCKET_EXT
|
||||
|
||||
create
|
||||
make_server_by_address_and_port,
|
||||
make_server_by_port,
|
||||
make_client_by_address_and_port,
|
||||
make_client_by_port,
|
||||
make_from_separate,
|
||||
make_empty
|
||||
|
||||
create {NETWORK_STREAM_SOCKET}
|
||||
make_from_descriptor_and_address
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
-- Create a network stream socket.
|
||||
do
|
||||
Precursor
|
||||
debug
|
||||
set_reuse_address
|
||||
end
|
||||
end
|
||||
|
||||
make_server_by_address_and_port (an_address: INET_ADDRESS; a_port: INTEGER)
|
||||
-- Create server socket on `an_address' and `a_port'.
|
||||
require
|
||||
valid_port: a_port >= 0
|
||||
do
|
||||
make
|
||||
create address.make_from_address_and_port (an_address, a_port)
|
||||
bind
|
||||
end
|
||||
|
||||
make_from_separate (s: separate STREAM_SOCKET)
|
||||
require
|
||||
descriptor_available: s.descriptor_available
|
||||
do
|
||||
create_from_descriptor (s.descriptor)
|
||||
end
|
||||
|
||||
feature -- Basic operation
|
||||
|
||||
peek_stream (nb_char: INTEGER)
|
||||
-- Read a string of at most `nb_char' characters without removing the data from the queue.
|
||||
-- Make result available in last_string.
|
||||
require
|
||||
readable: readable
|
||||
socket_exists: exists
|
||||
local
|
||||
ext: C_STRING
|
||||
retval: INTEGER
|
||||
l: like last_string
|
||||
do
|
||||
create ext.make_empty (nb_char + 1)
|
||||
retval := clib_recv (descriptor, ext.item, nb_char, c_peekmsg)
|
||||
if retval = 0 then
|
||||
last_string.wipe_out
|
||||
socket_error := Void
|
||||
elseif retval > 0 then
|
||||
ext.set_count (retval)
|
||||
l := last_string
|
||||
l.wipe_out
|
||||
l.grow (retval)
|
||||
l.set_count (retval)
|
||||
ext.read_substring_into (l, 1, retval)
|
||||
socket_error := Void
|
||||
else
|
||||
last_string.wipe_out
|
||||
socket_error := "Socket error (MSG_PEEK)"
|
||||
end
|
||||
ensure
|
||||
last_string_not_void: last_string /= Void
|
||||
end
|
||||
|
||||
send_message (a_msg: STRING)
|
||||
do
|
||||
put_string (a_msg)
|
||||
end
|
||||
|
||||
feature -- Output
|
||||
|
||||
put_readable_string_8 (s: READABLE_STRING_8)
|
||||
-- Write readable string `s' to socket.
|
||||
local
|
||||
ext: C_STRING
|
||||
do
|
||||
create ext.make (s)
|
||||
put_managed_pointer (ext.managed_data, 0, s.count)
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
has_incoming_data: BOOLEAN
|
||||
-- Check if Current has available data to be read.
|
||||
-- note: no data will not be removed from the queue.
|
||||
require
|
||||
socket_exists: exists
|
||||
do
|
||||
peek_stream (1)
|
||||
Result := last_string.count = 1
|
||||
end
|
||||
|
||||
try_ready_for_reading: BOOLEAN
|
||||
-- Is data available for reading from the socket right now?
|
||||
require
|
||||
socket_exists: exists
|
||||
local
|
||||
retval: INTEGER
|
||||
do
|
||||
retval := c_select_poll_with_timeout (descriptor, True, 0)
|
||||
Result := (retval > 0)
|
||||
end
|
||||
|
||||
feature {NONE} -- C implementation
|
||||
|
||||
clib_recv (a_fd: INTEGER; buf: POINTER; len: INTEGER; flags: INTEGER): INTEGER
|
||||
-- External routine to receive at most `len' number of
|
||||
-- bytes into buffer `buf' from socket `fd' with `flags' options.
|
||||
external
|
||||
"C inline"
|
||||
alias
|
||||
"[
|
||||
return (EIF_INTEGER) recv ((int) $a_fd, (char *) $buf, (int) $len, (int) $flags);
|
||||
]"
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
|
||||
end
|
||||
@@ -0,0 +1,160 @@
|
||||
note
|
||||
description: "[
|
||||
Until 16.05, the EiffelNet socket interface DOES NOT have
|
||||
- make_server_by_address_and_port
|
||||
- recv_timeout
|
||||
- send_timeout.
|
||||
|
||||
TO BE REMOVED IN THE FUTURE, WHEN 16.05 IS OLD.
|
||||
]"
|
||||
|
||||
deferred class
|
||||
HTTPD_STREAM_SOCKET_EXT
|
||||
|
||||
inherit
|
||||
PLATFORM
|
||||
|
||||
feature -- Initialization
|
||||
|
||||
make
|
||||
deferred
|
||||
end
|
||||
|
||||
make_server_by_address_and_port (a_address: INET_ADDRESS; a_port: INTEGER)
|
||||
-- Create server socket on `a_address' and `a_port'.
|
||||
require
|
||||
valid_port: a_port >= 0
|
||||
do
|
||||
make
|
||||
set_address (create {like address_type}.make_from_address_and_port (a_address, a_port))
|
||||
bind
|
||||
end
|
||||
|
||||
feature -- Basic operation
|
||||
|
||||
bind
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
set_address (addr: detachable like address_type)
|
||||
deferred
|
||||
end
|
||||
|
||||
address_type: NETWORK_SOCKET_ADDRESS
|
||||
deferred
|
||||
end
|
||||
|
||||
descriptor: INTEGER
|
||||
-- Socket descriptor of current socket
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Socket Recv and Send timeout.
|
||||
|
||||
set_recv_timeout (a_timeout_seconds: INTEGER)
|
||||
-- Set the receive timeout in seconds on Current socket.
|
||||
-- if `0' the related operations will never timeout.
|
||||
require
|
||||
positive_timeout: a_timeout_seconds >= 0
|
||||
do
|
||||
c_set_sock_recv_timeout (descriptor, level_sol_socket, a_timeout_seconds)
|
||||
end
|
||||
|
||||
set_send_timeout (a_timeout_seconds: INTEGER)
|
||||
-- Set the send timeout in milliseconds on Current socket.
|
||||
-- if `0' the related operations will never timeout.
|
||||
require
|
||||
positive_timeout: a_timeout_seconds >= 0
|
||||
do
|
||||
c_set_sock_send_timeout (descriptor, level_sol_socket, a_timeout_seconds)
|
||||
end
|
||||
|
||||
feature {NONE} -- Externals
|
||||
|
||||
level_sol_socket: INTEGER
|
||||
-- SOL_SOCKET level of options
|
||||
deferred
|
||||
end
|
||||
|
||||
c_set_sock_recv_timeout (a_fd, a_level: INTEGER; a_timeout_seconds: INTEGER)
|
||||
-- C routine to set socket option `SO_RCVTIMEO' with `a_timeout_seconds' seconds.
|
||||
external
|
||||
"C inline use %"ew_httpd_net.h%""
|
||||
alias
|
||||
"[
|
||||
#ifdef SO_RCVTIMEO
|
||||
int flag = SO_RCVTIMEO;
|
||||
#else
|
||||
int flag = 0x1006;
|
||||
#endif
|
||||
|
||||
#ifdef EIF_WINDOWS
|
||||
int arg = (int) 1000 * $a_timeout_seconds; /* Timeout in milliseconds */
|
||||
setsockopt((int) $a_fd, (int) $a_level, flag, (char *) &arg, sizeof(arg));
|
||||
#else
|
||||
struct timeval tv;
|
||||
tv.tv_sec = $a_timeout_seconds; /* Timeout in seconds */
|
||||
tv.tv_usec = 0;
|
||||
setsockopt((int) $a_fd, (int) $a_level, flag, (struct timeval *)&tv, sizeof(struct timeval));
|
||||
#endif
|
||||
]"
|
||||
end
|
||||
|
||||
c_set_sock_send_timeout (a_fd, a_level: INTEGER; a_timeout_seconds: INTEGER)
|
||||
-- C routine to set socket option `SO_SNDTIMEO' with `a_timeout_seconds' seconds.
|
||||
external
|
||||
"C inline use %"ew_httpd_net.h%""
|
||||
alias
|
||||
"[
|
||||
#ifdef SO_RCVTIMEO
|
||||
int flag = SO_SNDTIMEO;
|
||||
#else
|
||||
int flag = 0x1005;
|
||||
#endif
|
||||
#ifdef EIF_WINDOWS
|
||||
int arg = (int) 1000 * $a_timeout_seconds; /* Timeout in milliseconds */
|
||||
setsockopt((int) $a_fd, (int) $a_level, flag, (char *) &arg, sizeof(arg));
|
||||
#else
|
||||
struct timeval tv;
|
||||
tv.tv_sec = $a_timeout_seconds; /* Timeout in seconds */
|
||||
tv.tv_usec = 0;
|
||||
setsockopt((int) $a_fd, (int) $a_level, flag, (struct timeval *)&tv, sizeof(struct timeval));
|
||||
#endif
|
||||
]"
|
||||
end
|
||||
|
||||
feature {NONE} -- No-Exception network operation
|
||||
|
||||
c_recv_noexception (a_fd: INTEGER; buf: POINTER; len: INTEGER; flags: INTEGER): INTEGER
|
||||
-- External routine to read a `len' number of characters
|
||||
-- into buffer `buf' from socket `a_fd' with options `flags'.
|
||||
external
|
||||
"C inline use %"ew_httpd_net.h%""
|
||||
alias
|
||||
"[
|
||||
recv((int) $a_fd, (char *) $buf, (int) $len, (int) $flags)
|
||||
]"
|
||||
end
|
||||
|
||||
c_read_stream_noexception (a_fd: INTEGER; len: INTEGER; buf: POINTER): INTEGER
|
||||
-- External routine to read a `len' number of characters
|
||||
-- into buffer `buf' from socket `a_fd'.
|
||||
do
|
||||
Result := c_recv_noexception (a_fd, buf, len, 0)
|
||||
end
|
||||
|
||||
c_put_stream_noexception (a_fd: INTEGER; buf: POINTER; len: INTEGER): INTEGER
|
||||
-- External routine to write stream pointed by `s' of
|
||||
-- length `length' to socket `fd'.
|
||||
-- Note: does not raise exception on error, but return error value as Result.
|
||||
external
|
||||
"C inline use %"ew_httpd_net.h%""
|
||||
alias
|
||||
"[
|
||||
send((int) $a_fd, (char *) $buf, (int) $len, (int) 0)
|
||||
]"
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,41 @@
|
||||
note
|
||||
description: "[
|
||||
Extension to HTTPD_STREAM_SOCKET to support backward compatibility.
|
||||
|
||||
TO BE REMOVED IN THE FUTURE, WHEN 16.05 IS OLD.
|
||||
]"
|
||||
|
||||
deferred class
|
||||
HTTPD_STREAM_SSL_SOCKET_EXT
|
||||
|
||||
feature {NONE} -- SSL bridge
|
||||
|
||||
ssl_write (a_ssl: SSL; a_pointer: POINTER; a_byte_count: INTEGER): INTEGER
|
||||
do
|
||||
-- In delivery until 16.05
|
||||
-- SSL.write does not return any value!
|
||||
-- So let's use `c_ssl_write' from Current class
|
||||
-- instead of:
|
||||
-- a_ssl.write (a_pointer, a_byte_count)
|
||||
|
||||
Result := c_ssl_write (a_ssl.ptr, a_pointer, a_byte_count)
|
||||
if a_ssl.was_error then
|
||||
-- Until 16.05, there is no error check for `SSL.write'
|
||||
-- so nothing can be done here.
|
||||
|
||||
if Result >= 0 then
|
||||
Result := -1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
c_ssl_write (an_ssl_ptr: POINTER; buffer: POINTER; nb_bytes: INTEGER_32): INTEGER_32
|
||||
-- External call to SSL_write
|
||||
-- (export status {NONE})
|
||||
external
|
||||
"C use %"eif_openssl.h%""
|
||||
alias
|
||||
"SSL_write"
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,95 +0,0 @@
|
||||
note
|
||||
description: "[
|
||||
Until 16.05, the EiffelNet socket interface DOES NOT have recv_timeout and send_timeout.
|
||||
]"
|
||||
|
||||
deferred class
|
||||
TCP_STREAM_SOCKET_EXT
|
||||
|
||||
feature -- Access
|
||||
|
||||
descriptor: INTEGER
|
||||
-- Socket descriptor of current socket
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Socket Recv and Send timeout.
|
||||
|
||||
-- recv_timeout: INTEGER
|
||||
-- -- Receive timeout in seconds on Current socket.
|
||||
-- do
|
||||
-- Result := c_get_sock_recv_timeout (descriptor, level_sol_socket)
|
||||
-- ensure
|
||||
-- result_not_negative: Result >= 0
|
||||
-- end
|
||||
--
|
||||
-- send_timeout: INTEGER
|
||||
-- -- Send timeout in seconds on Current socket.
|
||||
-- do
|
||||
-- Result := c_get_sock_send_timeout (descriptor, level_sol_socket)
|
||||
-- ensure
|
||||
-- result_not_negative: Result >= 0
|
||||
-- end
|
||||
|
||||
set_recv_timeout (a_timeout_seconds: INTEGER)
|
||||
-- Set the receive timeout in seconds on Current socket.
|
||||
-- if `0' the related operations will never timeout.
|
||||
require
|
||||
positive_timeout: a_timeout_seconds >= 0
|
||||
do
|
||||
c_set_sock_recv_timeout (descriptor, level_sol_socket, a_timeout_seconds)
|
||||
end
|
||||
|
||||
set_send_timeout (a_timeout_seconds: INTEGER)
|
||||
-- Set the send timeout in milliseconds on Current socket.
|
||||
-- if `0' the related operations will never timeout.
|
||||
require
|
||||
positive_timeout: a_timeout_seconds >= 0
|
||||
do
|
||||
c_set_sock_send_timeout (descriptor, level_sol_socket, a_timeout_seconds)
|
||||
end
|
||||
|
||||
feature {NONE} -- Externals
|
||||
|
||||
level_sol_socket: INTEGER
|
||||
-- SOL_SOCKET level of options
|
||||
deferred
|
||||
end
|
||||
|
||||
c_set_sock_recv_timeout (a_fd, a_level: INTEGER; a_timeout_seconds: INTEGER)
|
||||
-- C routine to set socket option `SO_RCVTIMEO' with `a_timeout_seconds' seconds.
|
||||
external
|
||||
"C inline"
|
||||
alias
|
||||
"[
|
||||
#ifdef EIF_WINDOWS
|
||||
int arg = (int) 1000 * $a_timeout_seconds; /* Timeout in milliseconds */
|
||||
setsockopt((SOCKET) $a_fd, (int) $a_level, (int) SO_RCVTIMEO, (char *) &arg, sizeof(arg));
|
||||
#else
|
||||
struct timeval tv;
|
||||
tv.tv_sec = $a_timeout_seconds; /* Timeout in seconds */
|
||||
|
||||
setsockopt((int) $a_fd, (int) $a_level, (int) SO_RCVTIMEO, (struct timeval *)&tv, sizeof(struct timeval));
|
||||
#endif
|
||||
]"
|
||||
end
|
||||
|
||||
c_set_sock_send_timeout (a_fd, a_level: INTEGER; a_timeout_seconds: INTEGER)
|
||||
-- C routine to set socket option `SO_SNDTIMEO' with `a_timeout_seconds' seconds.
|
||||
external
|
||||
"C inline"
|
||||
alias
|
||||
"[
|
||||
#ifdef EIF_WINDOWS
|
||||
int arg = (int) 1000 * $a_timeout_seconds; /* Timeout in milliseconds */
|
||||
setsockopt((SOCKET) $a_fd, (int) $a_level, (int) SO_SNDTIMEO, (char *) &arg, sizeof(arg));
|
||||
#else
|
||||
struct timeval tv;
|
||||
tv.tv_sec = $a_timeout_seconds; /* Timeout in seconds */
|
||||
|
||||
setsockopt((int) $a_fd, (int) $a_level, (int) SO_SNDTIMEO, (struct timeval *)&tv, sizeof(struct timeval));
|
||||
#endif
|
||||
]"
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
indexing
|
||||
description: "Functions used by the EiffelWeb httpd networking classes. "
|
||||
copyright: "Copyright (c) 2011-2016, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
*/
|
||||
|
||||
#ifndef _ew_httpd_net_h_
|
||||
#define _ew_httpd_net_h_
|
||||
|
||||
#include "eif_config.h"
|
||||
|
||||
#ifdef EIF_WINDOWS
|
||||
# ifndef _WINSOCKAPI_
|
||||
# define FD_SETSIZE 256
|
||||
# include <winsock2.h>
|
||||
# include <Ws2tcpip.h>
|
||||
# include <stdio.h>
|
||||
# endif
|
||||
#else /* unix-specific */
|
||||
# include <sys/socket.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* extern declarations ... */
|
||||
#ifdef EIF_WINDOWS
|
||||
extern int setsockopt(int, int, int, char*, int);
|
||||
extern int recv(int, char *, int, int);
|
||||
extern int send(int, char *, int, int);
|
||||
#else
|
||||
extern int setsockopt(int, int, int, const void*, socklen_t);
|
||||
extern ssize_t recv(int, void *, size_t, int);
|
||||
extern ssize_t send(int, const void *, size_t, int);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -20,13 +20,19 @@ create
|
||||
feature {NONE} -- Factory
|
||||
|
||||
new_listening_socket (a_addr: detachable INET_ADDRESS; a_http_port: INTEGER): HTTPD_STREAM_SOCKET
|
||||
local
|
||||
s_ssl: HTTPD_STREAM_SSL_SOCKET
|
||||
do
|
||||
if configuration.is_secure then
|
||||
if a_addr /= Void then
|
||||
create {HTTPD_STREAM_SSL_SOCKET} Result.make_ssl_server_by_address_and_port (a_addr, a_http_port, configuration.ssl_protocol, configuration.ca_crt, configuration.ca_key)
|
||||
create s_ssl.make_server_by_address_and_port (a_addr, a_http_port)
|
||||
Result := s_ssl
|
||||
else
|
||||
create {HTTPD_STREAM_SSL_SOCKET} Result.make_ssl_server_by_port (a_http_port, configuration.ssl_protocol, configuration.ca_crt, configuration.ca_key)
|
||||
create s_ssl.make_server_by_port (a_http_port)
|
||||
end
|
||||
s_ssl.set_tls_protocol (configuration.ssl_protocol)
|
||||
s_ssl.set_certificate_filenames (configuration.ca_crt, configuration.ca_key)
|
||||
Result := s_ssl
|
||||
else
|
||||
Result := Precursor (a_addr, a_http_port)
|
||||
end
|
||||
|
||||
@@ -35,10 +35,10 @@ feature {NONE} -- Initialization
|
||||
initialize_server (server)
|
||||
end
|
||||
|
||||
make_with_base (a_base: like base)
|
||||
make_with_base (a_base: detachable separate READABLE_STRING_8)
|
||||
-- Create current standalone connector with base url `a_base'
|
||||
require
|
||||
a_base_starts_with_slash: (a_base /= Void and then not a_base.is_empty) implies a_base.starts_with ("/")
|
||||
a_base_starts_with_slash: (a_base /= Void and then not a_base.is_empty) implies is_valid_base (a_base)
|
||||
do
|
||||
make
|
||||
set_base (a_base)
|
||||
@@ -109,7 +109,8 @@ feature -- Status report
|
||||
feature -- Callbacks
|
||||
|
||||
on_launched_actions: ACTION_SEQUENCE [TUPLE [WGI_STANDALONE_CONNECTOR [WGI_EXECUTION]]]
|
||||
-- Actions triggered when launched
|
||||
-- Actions triggered when launched.
|
||||
-- WARNING: only supported for now with SCOOP concurrency mode. [2016-oct-07]
|
||||
|
||||
feature -- Event
|
||||
|
||||
@@ -123,16 +124,25 @@ feature -- Event
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_base (v: like base)
|
||||
set_base (v: detachable separate READABLE_STRING_8)
|
||||
-- Set base url `base' to `v'.
|
||||
require
|
||||
b_starts_with_slash: (v /= Void and then not v.is_empty) implies v.starts_with ("/")
|
||||
b_starts_with_slash: (v /= Void and then not v.is_empty) implies is_valid_base (v)
|
||||
do
|
||||
base := v
|
||||
if v = Void then
|
||||
base := Void
|
||||
else
|
||||
create {STRING_8} base.make_from_separate (v)
|
||||
end
|
||||
ensure
|
||||
valid_base: (attached base as l_base and then not l_base.is_empty) implies l_base.starts_with ("/")
|
||||
end
|
||||
|
||||
is_valid_base (v: separate READABLE_STRING_8): BOOLEAN
|
||||
do
|
||||
Result := not v.is_whitespace and then v[1] = '/'
|
||||
end
|
||||
|
||||
set_port_number (a_port_number: INTEGER)
|
||||
-- Set port number to `a_port_number'.
|
||||
require
|
||||
@@ -141,6 +151,13 @@ feature -- Element change
|
||||
set_port_on_configuration (a_port_number, configuration)
|
||||
end
|
||||
|
||||
set_socket_recv_timeout (a_nb_seconds: INTEGER)
|
||||
require
|
||||
a_nb_seconds_positive_or_zero: a_nb_seconds >= 0
|
||||
do
|
||||
set_socket_recv_timeout_on_configuration (a_nb_seconds, configuration)
|
||||
end
|
||||
|
||||
set_max_concurrent_connections (nb: INTEGER)
|
||||
-- Set maximum concurrent connections to `nb'.
|
||||
require
|
||||
@@ -164,6 +181,13 @@ feature -- Element change
|
||||
|
||||
feature -- Server
|
||||
|
||||
launch_on_port (a_port_number: INTEGER)
|
||||
-- Launch server listening on port `a_port_number'.
|
||||
do
|
||||
set_port_number (a_port_number)
|
||||
launch
|
||||
end
|
||||
|
||||
launch
|
||||
-- Launch web server listening.
|
||||
do
|
||||
@@ -189,12 +213,12 @@ feature -- Events
|
||||
require
|
||||
obs.started -- SCOOP wait condition.
|
||||
do
|
||||
-- FIXME: this works only with SCOOP concurrency mode. [2016-oct-07]
|
||||
if obs.port > 0 then
|
||||
on_launched (obs.port)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
server_controller (a_server: like server): separate HTTPD_CONTROLLER
|
||||
@@ -238,6 +262,11 @@ feature {NONE} -- Implementation: element change
|
||||
cfg.set_http_server_port (a_port_number)
|
||||
end
|
||||
|
||||
set_socket_recv_timeout_on_configuration (a_nb_seconds: INTEGER; cfg: like configuration)
|
||||
do
|
||||
cfg.set_socket_recv_timeout (a_nb_seconds)
|
||||
end
|
||||
|
||||
set_max_concurrent_connections_on_configuration (nb: INTEGER; cfg: like configuration)
|
||||
do
|
||||
cfg.set_max_concurrent_connections (nb)
|
||||
|
||||
@@ -42,8 +42,8 @@ feature -- Input
|
||||
src: like source
|
||||
do
|
||||
src := source
|
||||
if src.readable then
|
||||
src.read_character
|
||||
if src.readable and not src.was_error then
|
||||
src.read_character_noexception
|
||||
last_character := src.last_character
|
||||
else
|
||||
last_character := '%U'
|
||||
@@ -56,8 +56,8 @@ feature -- Input
|
||||
do
|
||||
src := source
|
||||
last_string.wipe_out
|
||||
if src.readable then
|
||||
src.read_stream_thread_aware (nb)
|
||||
if src.readable and not src.was_error then
|
||||
src.read_stream_noexception (nb)
|
||||
last_string.append_string (src.last_string)
|
||||
end
|
||||
end
|
||||
@@ -85,11 +85,11 @@ feature -- Status report
|
||||
end_of_input: BOOLEAN
|
||||
-- Has the end of input stream been reached?
|
||||
do
|
||||
Result := not source.readable
|
||||
Result := not source.readable or source.was_error
|
||||
end
|
||||
|
||||
;note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -75,23 +75,23 @@ feature -- Output
|
||||
-- Send `s' to http client
|
||||
do
|
||||
last_target_call_succeed := False
|
||||
target.put_readable_string_8 (s)
|
||||
last_target_call_succeed := True
|
||||
target.put_readable_string_8_noexception (s)
|
||||
last_target_call_succeed := not target.was_error
|
||||
end
|
||||
|
||||
put_string (s: READABLE_STRING_8)
|
||||
-- Send `s' to http client
|
||||
do
|
||||
last_target_call_succeed := False
|
||||
target.put_readable_string_8 (s)
|
||||
last_target_call_succeed := True
|
||||
target.put_readable_string_8_noexception (s)
|
||||
last_target_call_succeed := not target.was_error
|
||||
end
|
||||
|
||||
put_character (c: CHARACTER_8)
|
||||
do
|
||||
last_target_call_succeed := False
|
||||
target.put_character (c)
|
||||
last_target_call_succeed := True
|
||||
target.put_character_noexception (c)
|
||||
last_target_call_succeed := not target.was_error
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
@@ -116,7 +116,7 @@ feature -- Basic operations
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</option>
|
||||
<setting name="concurrency" value="thread"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="connector_nino" location="..\..\connectors\nino\nino-safe.ecf" readonly="false"/>
|
||||
<library name="connector_standalone" location="..\..\connectors\standalone\standalone-safe.ecf" readonly="false"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi-safe.ecf" readonly="false"/>
|
||||
<cluster name="src" location="src\" recursive="true"/>
|
||||
</target>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</option>
|
||||
<setting name="concurrency" value="thread"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="connector_nino" location="..\..\connectors\nino\nino.ecf" readonly="false"/>
|
||||
<library name="connector_standalone" location="..\..\connectors\standalone\standalone.ecf" readonly="false"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi.ecf" readonly="false"/>
|
||||
<cluster name="src" location="src\" recursive="true"/>
|
||||
</target>
|
||||
|
||||
@@ -14,14 +14,14 @@ feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
do
|
||||
print ("Example: start a Nino web server on port " + port_number.out + ", %Nand reply Hello World for any request such as http://localhost:8123/%N")
|
||||
(create {NINO_SERVICE [HELLO_WORLD_EXECUTION]}.make_custom ("")).listen (port_number)
|
||||
print ("Example: start a Standalone web server on port " + port_number.out + ", %Nand reply Hello World for any request such as http://localhost:8123/%N")
|
||||
(create {WGI_STANDALONE_CONNECTOR [HELLO_WORLD_EXECUTION]}.make_with_base ("")).launch_on_port (port_number)
|
||||
end
|
||||
|
||||
port_number: INTEGER = 8123
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Eiffel Software and others"
|
||||
copyright: "2011-2016, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -18,12 +18,12 @@ feature {NONE} -- Initialization
|
||||
execute
|
||||
do
|
||||
response.set_status_code (200, Void)
|
||||
response.put_header_text ("Content-Type: text/plain%R%N")
|
||||
response.put_header_text ("Content-Length: 13%R%NContent-Type: text/plain%R%N")
|
||||
response.put_string ("Hello World!%N")
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Eiffel Software and others"
|
||||
copyright: "2011-2016, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -12,11 +12,12 @@
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="connector_cgi" location="..\..\ewsgi\connectors\cgi\cgi-safe.ecf"/>
|
||||
<library name="connector_libfcgi" location="..\..\ewsgi\connectors\libfcgi\libfcgi-safe.ecf"/>
|
||||
<library name="connector_nino" location="..\..\ewsgi\connectors\nino\nino-safe.ecf"/>
|
||||
<library name="connector_standalone" location="..\..\ewsgi\connectors\standalone\standalone-safe.ecf"/>
|
||||
<library name="encoder" location="..\..\..\text\encoder\encoder-safe.ecf" readonly="false"/>
|
||||
<library name="error" location="..\..\..\utility\general\error\error-safe.ecf"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi\ewsgi-safe.ecf"/>
|
||||
<library name="http" location="..\..\..\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="standalone" location="standalone-safe.ecf" readonly="false"/>
|
||||
<library name="nino" location="nino-safe.ecf" readonly="false">
|
||||
<renaming old_name="HTTP_CONSTANTS" new_name="NINO_HTTP_CONSTANTS"/>
|
||||
</library>
|
||||
@@ -24,6 +25,6 @@
|
||||
<library name="wsf" location="..\wsf-safe.ecf"/>
|
||||
<cluster name="wsf_cgi" location=".\cgi\" recursive="true"/>
|
||||
<cluster name="wsf_libfcgi" location=".\libfcgi\" recursive="true"/>
|
||||
<cluster name="wsf_nino" location=".\nino\" recursive="true"/>
|
||||
<cluster name="wsf_standalone" location=".\standalone\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi\ewsgi-safe.ecf"/>
|
||||
<library name="wsf" location="..\wsf-safe.ecf"/>
|
||||
<library name="wsf_connector_nino" location="nino-safe.ecf"/>
|
||||
<library name="wsf_connector_standalone" location="standalone-safe.ecf"/>
|
||||
<cluster name="wsf_openshift" location=".\openshift\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -2,13 +2,12 @@ note
|
||||
description: "[
|
||||
Component to launch the service using the default connector
|
||||
|
||||
Eiffel Web Nino customized for OpenShift
|
||||
EiffelWeb standalone customized for OpenShift
|
||||
|
||||
|
||||
This default connector support options:
|
||||
base: base_url (very specific to standalone server)
|
||||
verbose: to display verbose output, useful for Nino
|
||||
force_single_threaded: use only one thread, useful for Nino
|
||||
verbose: to display verbose output, useful for standalone
|
||||
|
||||
check WSF_SERVICE_LAUNCHER for more documentation
|
||||
]"
|
||||
@@ -19,7 +18,7 @@ class
|
||||
WSF_OPENSHIFT_SERVICE_LAUNCHER [G -> WSF_EXECUTION create make end]
|
||||
|
||||
inherit
|
||||
WSF_NINO_SERVICE_LAUNCHER [G]
|
||||
WSF_STANDALONE_SERVICE_LAUNCHER [G]
|
||||
redefine
|
||||
initialize
|
||||
end
|
||||
|
||||
@@ -64,7 +64,7 @@ feature {NONE} -- Initialization
|
||||
verbose := False
|
||||
verbose_level := notice_level
|
||||
|
||||
base_url := ""
|
||||
base_url := Void
|
||||
|
||||
if attached options as opts then
|
||||
if attached {READABLE_STRING_GENERAL} opts.option ("server_name") as l_server_name then
|
||||
@@ -175,7 +175,12 @@ feature -- Execution
|
||||
else
|
||||
io.error.put_string ("localhost")
|
||||
end
|
||||
io.error.put_string (":" + port_number.out + "/" + base_url + "%N")
|
||||
io.error.put_string (":" + port_number.out)
|
||||
if attached base_url as b and then not b.is_empty then
|
||||
io.error.put_string (b + "%N")
|
||||
else
|
||||
io.error.put_string ("/%N")
|
||||
end
|
||||
end
|
||||
end
|
||||
update_configuration (conn.configuration)
|
||||
@@ -201,7 +206,7 @@ feature {NONE} -- Implementation
|
||||
|
||||
server_name: detachable READABLE_STRING_8
|
||||
|
||||
base_url: READABLE_STRING_8
|
||||
base_url: detachable READABLE_STRING_8
|
||||
|
||||
verbose: BOOLEAN
|
||||
verbose_level: INTEGER
|
||||
|
||||
@@ -2,11 +2,10 @@ note
|
||||
description: "[
|
||||
Options used by WSF_SERVICE_LAUNCHER
|
||||
|
||||
For instance options supported by Nino as default connector::
|
||||
For instance options supported by Standalone as default connector::
|
||||
port: numeric such as 8099 (or equivalent string as "8099")
|
||||
base: base_url (very specific to standalone server)
|
||||
force_single_threaded: use only one thread, useful for Nino
|
||||
verbose: to display verbose output, useful for Nino
|
||||
verbose: to display verbose output, useful for Standalone
|
||||
]"
|
||||
date: "$Date: 2016-08-06 13:34:52 +0200 (sam., 06 août 2016) $"
|
||||
revision: "$Revision: 99106 $"
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
</option>
|
||||
<setting name="concurrency" value="thread"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="connector_nino" location="..\..\..\ewsgi\connectors\nino\nino-safe.ecf" readonly="false"/>
|
||||
<library name="connector_standalone" location="..\..\..\ewsgi\connectors\standalone\standalone-safe.ecf" readonly="false"/>
|
||||
<library name="connector_null" location="..\..\..\ewsgi\connectors\null\null-safe.ecf" readonly="false"/>
|
||||
<library name="dft_nino" location="..\..\default\nino-safe.ecf"/>
|
||||
<library name="dft_standalone" location="..\..\default\standalone-safe.ecf"/>
|
||||
<library name="ewsgi" location="..\..\..\ewsgi\ewsgi-safe.ecf" readonly="false"/>
|
||||
<library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
|
||||
<library name="wsf" location="..\..\wsf-safe.ecf" readonly="false"/>
|
||||
|
||||
@@ -13,11 +13,17 @@ feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
-- Initialize `Current'.
|
||||
local
|
||||
base_url: detachable READABLE_STRING_8
|
||||
do
|
||||
print ("Test Server that could be used for autotest%N")
|
||||
-- base_url := "/test/"
|
||||
base_url := {TEST_SETTINGS}.base_url
|
||||
if base_url.is_whitespace then
|
||||
base_url := Void
|
||||
end
|
||||
|
||||
set_service_option ("port", 9091)
|
||||
set_service_option ("port", {TEST_SETTINGS}.port_number)
|
||||
set_service_option ("base", base_url)
|
||||
set_service_option ("verbose", True)
|
||||
make_and_launch
|
||||
end
|
||||
|
||||
@@ -35,6 +35,13 @@ feature -- Helper
|
||||
end
|
||||
|
||||
base_url: detachable STRING
|
||||
once
|
||||
Result := {TEST_SETTINGS}.base_url
|
||||
|
||||
if Result.is_whitespace then
|
||||
Result := Void
|
||||
end
|
||||
end
|
||||
|
||||
test_url (a_query_url: READABLE_STRING_8): READABLE_STRING_8
|
||||
local
|
||||
|
||||
16
library/server/wsf/tests/server/test_settings.e
Normal file
16
library/server/wsf/tests/server/test_settings.e
Normal file
@@ -0,0 +1,16 @@
|
||||
note
|
||||
description: "Summary description for {TEST_SETTINGS}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
TEST_SETTINGS
|
||||
|
||||
feature -- Access
|
||||
|
||||
port_number: INTEGER = 9091
|
||||
|
||||
base_url: STRING = "" --"/test/"
|
||||
|
||||
end
|
||||
@@ -19,33 +19,49 @@ inherit
|
||||
|
||||
feature {NONE} -- Events
|
||||
|
||||
web_app: detachable NINO_SERVICE [TEST_EXECUTION]
|
||||
web_connector: detachable separate WGI_STANDALONE_CONNECTOR [TEST_EXECUTION]
|
||||
|
||||
port_number: INTEGER
|
||||
base_url: detachable STRING
|
||||
base_url: detachable separate STRING
|
||||
once
|
||||
if attached local_base_url as b and then not b.is_whitespace then
|
||||
create Result.make_from_separate (b)
|
||||
end
|
||||
end
|
||||
|
||||
local_base_url: detachable STRING
|
||||
once
|
||||
create Result.make_from_string ({TEST_SETTINGS}.base_url)
|
||||
if Result.is_whitespace then
|
||||
Result := Void
|
||||
end
|
||||
end
|
||||
|
||||
on_prepare
|
||||
-- <Precursor>
|
||||
local
|
||||
app: NINO_SERVICE [TEST_EXECUTION]
|
||||
wt: WORKER_THREAD
|
||||
conn: separate WGI_STANDALONE_CONNECTOR [TEST_EXECUTION]
|
||||
e: EXECUTION_ENVIRONMENT
|
||||
do
|
||||
create e
|
||||
-- port_number := 9091 -- Uncomment to use with server outside this process
|
||||
-- port_number := {TEST_SETTINGS}.port_number -- Uncomment to use with server outside this process
|
||||
if port_number = 0 then
|
||||
server_log ("== Current directory: " + e.current_working_directory)
|
||||
|
||||
port_number := 0
|
||||
base_url := "/test/"
|
||||
create app.make_custom (base_url)
|
||||
web_app := app
|
||||
|
||||
create wt.make (agent app.listen (port_number))
|
||||
wt.launch
|
||||
e.sleep (1_000_000_000 * 5)
|
||||
port_number := app.port
|
||||
server_log ("Server port=" + port_number.out)
|
||||
if attached base_url as b then
|
||||
create conn.make_with_base (b)
|
||||
else
|
||||
create conn.make
|
||||
end
|
||||
web_connector := conn
|
||||
setup_connector (conn)
|
||||
launch_connector (conn)
|
||||
|
||||
-- e.sleep (1_000_000_000 * 5)
|
||||
get_port_number (conn)
|
||||
|
||||
-- get_port_number (app.connector)
|
||||
else
|
||||
server_log ("Use existing server")
|
||||
server_log ("== Current directory: " + e.current_working_directory)
|
||||
@@ -53,6 +69,26 @@ feature {NONE} -- Events
|
||||
end
|
||||
end
|
||||
|
||||
setup_connector (conn: attached like web_connector)
|
||||
do
|
||||
conn.set_is_verbose (True)
|
||||
conn.set_port_number (port_number)
|
||||
conn.set_socket_recv_timeout (5)
|
||||
end
|
||||
|
||||
launch_connector (conn: attached like web_connector)
|
||||
do
|
||||
conn.launch
|
||||
end
|
||||
|
||||
get_port_number (conn: attached like web_connector)
|
||||
require
|
||||
conn.port > 0
|
||||
do
|
||||
port_number := conn.port
|
||||
server_log ("Server port=" + port_number.out)
|
||||
end
|
||||
|
||||
server_log_name: STRING
|
||||
local
|
||||
fn: FILE_NAME
|
||||
@@ -78,9 +114,9 @@ feature {NONE} -- Events
|
||||
|
||||
test_url (a_query_url: READABLE_STRING_8): READABLE_STRING_8
|
||||
local
|
||||
b: like base_url
|
||||
b: like local_base_url
|
||||
do
|
||||
b := base_url
|
||||
b := local_base_url
|
||||
if b = Void then
|
||||
b := ""
|
||||
end
|
||||
@@ -90,24 +126,29 @@ feature {NONE} -- Events
|
||||
on_clean
|
||||
-- <Precursor>
|
||||
do
|
||||
if attached web_app as app then
|
||||
app.shutdown
|
||||
if attached web_connector as conn then
|
||||
shutdown_server (conn)
|
||||
end
|
||||
end
|
||||
|
||||
shutdown_server (conn: attached like web_connector)
|
||||
do
|
||||
conn.shutdown_server
|
||||
end
|
||||
|
||||
http_session: detachable HTTP_CLIENT_SESSION
|
||||
|
||||
get_http_session
|
||||
local
|
||||
h: LIBCURL_HTTP_CLIENT
|
||||
b: like base_url
|
||||
h: DEFAULT_HTTP_CLIENT
|
||||
b: like local_base_url
|
||||
do
|
||||
create h.make
|
||||
b := base_url
|
||||
create h
|
||||
b := local_base_url
|
||||
if b = Void then
|
||||
b := "/"
|
||||
end
|
||||
if attached {HTTP_CLIENT_SESSION} h.new_session ("localhost:" + port_number.out + b) as sess then
|
||||
if attached {HTTP_CLIENT_SESSION} h.new_session ("http://localhost:" + port_number.out + b) as sess then
|
||||
http_session := sess
|
||||
sess.set_timeout (-1)
|
||||
sess.set_is_debug (True)
|
||||
@@ -120,15 +161,24 @@ feature {NONE} -- Events
|
||||
do
|
||||
get_http_session
|
||||
if attached http_session as sess then
|
||||
print ("Request: " + a_url + " ...%N")
|
||||
if attached sess.get (a_url, adapted_context (ctx)) as res then
|
||||
if attached res.body as l_body then
|
||||
if res.error_occurred then
|
||||
assert ("Request %""+a_url+"%" failed, got=[" + l_body + "]", False)
|
||||
if attached res.error_message as err_msg then
|
||||
assert ("Request %""+a_url+"%" failed, got=[" + l_body + "] error:" + err_msg, False)
|
||||
else
|
||||
assert ("Request %""+a_url+"%" failed, got=[" + l_body + "] error:N/A", False)
|
||||
end
|
||||
else
|
||||
assert ("Good answer got=%""+l_body+"%" expected=%""+a_expected_body+"%"", l_body.same_string (a_expected_body))
|
||||
end
|
||||
else
|
||||
assert ("Request %""+a_url+"%" failed, no body, status=" + res.status.out , False)
|
||||
if attached res.error_message as err_msg then
|
||||
assert ("Request %""+a_url+"%" failed, no body, status=" + res.status.out + " error:" + err_msg, False)
|
||||
else
|
||||
assert ("Request %""+a_url+"%" failed, no body, status=" + res.status.out + " error:N/A", False)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -146,18 +196,34 @@ feature {NONE} -- Events
|
||||
end
|
||||
end
|
||||
|
||||
test_post_request_with_filename (a_url: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT; a_fn: STRING; a_expected_body: READABLE_STRING_8)
|
||||
test_post_request_with_filename (a_url: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT; a_fn: STRING; a_expected_body: detachable READABLE_STRING_8; a_expected_starting_body: detachable READABLE_STRING_8)
|
||||
do
|
||||
get_http_session
|
||||
if attached http_session as sess then
|
||||
if attached sess.post_file (a_url, adapted_context (ctx), a_fn) as res and then not res.error_occurred and then attached res.body as l_body then
|
||||
assert ("Good answer got=%""+l_body+"%" expected=%""+a_expected_body+"%"", l_body.same_string (a_expected_body))
|
||||
if
|
||||
attached sess.post_file (a_url, adapted_context (ctx), a_fn) as res and then
|
||||
not res.error_occurred and then
|
||||
attached res.body as l_body
|
||||
then
|
||||
assert ("Good answer got=%""+l_body+"%" expected=%""+ safe_out (a_expected_body) +"%"",
|
||||
(a_expected_body /= Void implies l_body.same_string (a_expected_body))
|
||||
and (a_expected_starting_body /= Void implies l_body.starts_with (a_expected_starting_body))
|
||||
)
|
||||
else
|
||||
assert ("Request %""+a_url+"%" failed", False)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
safe_out (s: detachable READABLE_STRING_8): STRING
|
||||
do
|
||||
if s = Void then
|
||||
Result := "Void"
|
||||
else
|
||||
Result := s.out
|
||||
end
|
||||
end
|
||||
|
||||
adapted_context (ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_REQUEST_CONTEXT
|
||||
do
|
||||
if ctx /= Void then
|
||||
@@ -173,6 +239,7 @@ feature -- Test routines
|
||||
test_get_request_01
|
||||
-- New test routine
|
||||
do
|
||||
assert ("has port", port_number > 0)
|
||||
get_http_session
|
||||
if attached http_session as sess then
|
||||
test_get_request ("get/01", Void, "get-01")
|
||||
@@ -199,11 +266,11 @@ feature -- Test routines
|
||||
s := "This is an uploaded file%NTesting purpose%N"
|
||||
f.put_string (s)
|
||||
f.close
|
||||
test_post_request_with_filename ("post/file/01", Void, fn.string, "post-file-01%N" + s)
|
||||
test_post_request_with_filename ("post/file/01 #1", Void, fn.string, "post-file-01", "post-file-01")
|
||||
|
||||
create ctx.make
|
||||
ctx.add_form_parameter ("foo", "bar")
|
||||
test_post_request_with_filename ("post/file/01", ctx, fn.string, "post-file-01%N" + s)
|
||||
test_post_request_with_filename ("post/file/01 #2", ctx, fn.string, Void, "post-file-01")
|
||||
else
|
||||
assert ("not_implemented", False)
|
||||
end
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="wsf_tests" uuid="C4FF9CDA-B4E4-4841-97E0-7F799B85B657">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-15-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-15-0 http://www.eiffel.com/developers/xml/configuration-1-15-0.xsd" name="wsf_tests" uuid="C4FF9CDA-B4E4-4841-97E0-7F799B85B657">
|
||||
<target name="server">
|
||||
<root class="TEST" feature="make"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<option debug="true" warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="provisional">
|
||||
<option debug="true" warning="true" full_class_checking="true" is_attached_by_default="true" is_obsolete_routine_type="true" void_safety="all" syntax="provisional">
|
||||
<assertions precondition="true" postcondition="true" check="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<setting name="concurrency" value="thread"/>
|
||||
<setting name="concurrency" value="scoop"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="connector_nino" location="..\..\ewsgi\connectors\nino\nino-safe.ecf" readonly="false"/>
|
||||
<library name="connector_null" location="..\..\ewsgi\connectors\null\null-safe.ecf" readonly="false"/>
|
||||
<library name="dft_nino" location="..\default\nino-safe.ecf"/>
|
||||
<library name="connector_standalone" location="..\..\ewsgi\connectors\standalone\standalone-safe.ecf" readonly="false"/>
|
||||
<library name="dft_standalone" location="..\default\standalone-safe.ecf"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi\ewsgi-safe.ecf" readonly="false">
|
||||
<option>
|
||||
<assertions precondition="true" postcondition="true" check="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
</library>
|
||||
<library name="http" location="..\..\..\network\protocol\http\http-safe.ecf" readonly="false"/>
|
||||
<library name="http_client" location="..\..\..\network\http_client\http_client-safe.ecf" readonly="false"/>
|
||||
<library name="http_client" location="..\..\..\network\http_client\net_http_client-safe.ecf" readonly="false"/>
|
||||
<library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
||||
<library name="wsf" location="..\wsf-safe.ecf" readonly="false">
|
||||
@@ -29,6 +29,7 @@
|
||||
<assertions precondition="true" postcondition="true" check="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
</library>
|
||||
<library name="wsf_standalone" location="..\..\wsf\connector\standalone-safe.ecf" readonly="false"/>
|
||||
<cluster name="server" location=".\server\" recursive="true"/>
|
||||
</target>
|
||||
<target name="wsf_tests" extends="server">
|
||||
|
||||
@@ -11,15 +11,16 @@
|
||||
</option>
|
||||
<setting name="concurrency" value="thread"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="connector_nino" location="..\..\ewsgi\connectors\nino\nino.ecf" readonly="false"/>
|
||||
<library name="connector_null" location="..\..\ewsgi\connectors\null\null.ecf" readonly="false"/>
|
||||
<library name="dft_nino" location="..\default\nino.ecf"/>
|
||||
<library name="connector_standalone" location="..\..\ewsgi\connectors\standalone\standalone.ecf" readonly="false"/>
|
||||
<library name="dft_standalone" location="..\default\standalone.ecf"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi\ewsgi.ecf" readonly="false"/>
|
||||
<library name="http" location="..\..\..\network\protocol\http\http.ecf" readonly="false"/>
|
||||
<library name="http_client" location="..\..\..\network\http_client\http_client.ecf" readonly="false"/>
|
||||
<library name="http_client" location="..\..\..\network\http_client\net_http_client.ecf" readonly="false"/>
|
||||
<library name="thread" location="$ISE_LIBRARY\library\thread\thread.ecf"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
||||
<library name="wsf" location="..\wsf.ecf" readonly="false"/>
|
||||
<library name="wsf_standalone" location="..\..\wsf\connector\standalone.ecf" readonly="false"/>
|
||||
<cluster name="server" location=".\server\" recursive="true"/>
|
||||
</target>
|
||||
<target name="wsf_tests" extends="server">
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
{if condition="$WIZ.connectors.use_cgi ~ $WIZ_YES"}<library name="cgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\cgi-safe.ecf"/>{/if}
|
||||
{if condition="$WIZ.connectors.use_libfcgi ~ $WIZ_YES"}<library name="libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\libfcgi-safe.ecf"/>{/if}
|
||||
{if condition="$WIZ.connectors.use_standalone ~ $WIZ_YES"}<library name="standalone" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\standalone-safe.ecf"/>{/if}
|
||||
{if condition="$WIZ.connectors.use_nino ~ $WIZ_YES"}<library name="nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\nino-safe.ecf"/>{/if}
|
||||
<cluster name="launcher" location=".\launcher\" recursive="true">
|
||||
<cluster name="any_launcher" location="$|any"/>
|
||||
</cluster>
|
||||
@@ -35,16 +34,6 @@
|
||||
</cluster>
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
</target>{/if}
|
||||
{if condition="$WIZ.connectors.use_nino ~ $WIZ_YES"}
|
||||
<target name="{$WIZ.project.name/}_nino" extends="common">
|
||||
<root class="{$APP_ROOT/}" feature="make_and_launch"/>
|
||||
<setting name="concurrency" value="none"/>
|
||||
<library name="default_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\nino-safe.ecf"/>
|
||||
<cluster name="launcher" location=".\launcher\">
|
||||
<cluster name="default_launcher" location="$|default"/>
|
||||
</cluster>
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
</target>{/if}
|
||||
{if condition="$WIZ.connectors.use_cgi ~ $WIZ_YES"}
|
||||
<target name="{$WIZ.project.name/}_cgi" extends="common">
|
||||
<root class="{$APP_ROOT/}" feature="make_and_launch"/>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# For nino connector, use port {$WIZ.standalone_connector.port/}
|
||||
# For Standalone connector, use port {$WIZ.standalone_connector.port/}
|
||||
port={$WIZ.standalone_connector.port/}
|
||||
|
||||
#verbose=true
|
||||
|
||||
@@ -31,7 +31,7 @@ feature -- Execution
|
||||
-- Choose a default -> standalone
|
||||
create {WSF_STANDALONE_SERVICE_LAUNCHER} launcher.make_and_launch (opts){/literal}{/if}
|
||||
{if condition="$WIZ.connectors.use_standalone ~ $WIZ_YES"}{literal}
|
||||
elseif is_nino_launcher_id (l_id) then
|
||||
elseif is_standalone_launcher_id (l_id) then
|
||||
create {WSF_STANDALONE_SERVICE_LAUNCHER} launcher.make_and_launch (opts){/literal}{/if}
|
||||
{if condition="$WIZ.connectors.use_libfcgi ~ $WIZ_YES"}{literal}
|
||||
elseif is_libfcgi_launcher_id (l_id) then
|
||||
@@ -39,9 +39,9 @@ feature -- Execution
|
||||
{if condition="$WIZ.connectors.use_cgi ~ $WIZ_YES"}{literal}
|
||||
elseif is_cgi_launcher_id (l_id) then
|
||||
create {WSF_CGI_SERVICE_LAUNCHER} launcher.make_and_launch (opts){/literal}{/if}
|
||||
{if condition="$WIZ.connectors.use_nino ~ $WIZ_YES"}{literal}
|
||||
elseif is_nino_launcher_id (l_id) then
|
||||
create {WSF_NINO_SERVICE_LAUNCHER} launcher.make_and_launch (opts){/literal}{/if}
|
||||
{if condition="$WIZ.connectors.use_standalone ~ $WIZ_YES"}{literal}
|
||||
elseif is_standalone_launcher_id (l_id) then
|
||||
create {WSF_STANDALONE_SERVICE_LAUNCHER} launcher.make_and_launch (opts){/literal}{/if}
|
||||
{literal}
|
||||
else
|
||||
io.error.put_string ("Application launcher not found!%N")
|
||||
@@ -52,7 +52,7 @@ feature -- Execution
|
||||
launcher_id: detachable READABLE_STRING_GENERAL
|
||||
-- Launcher id based on the executable extension name if any.
|
||||
-- This can be redefine to customize for your application.
|
||||
--| ex: nino, cgi, libfcgi or Void.
|
||||
--| ex: standalone, cgi, libfcgi or Void.
|
||||
do
|
||||
if attached (create {PATH}.make_from_string (execution_environment.arguments.command_name)).extension as ext then
|
||||
Result := ext
|
||||
@@ -62,17 +62,11 @@ feature -- Execution
|
||||
feature -- Status report
|
||||
{/literal}
|
||||
{if condition="$WIZ.connectors.use_standalone ~ $WIZ_YES"}
|
||||
is_nino_launcher_id (a_id: READABLE_STRING_GENERAL): BOOLEAN
|
||||
is_standalone_launcher_id (a_id: READABLE_STRING_GENERAL): BOOLEAN
|
||||
do
|
||||
Result := a_id.is_case_insensitive ("standalone")
|
||||
end{/if}
|
||||
|
||||
{if condition="$WIZ.connectors.use_nino ~ $WIZ_YES"}
|
||||
is_nino_launcher_id (a_id: READABLE_STRING_GENERAL): BOOLEAN
|
||||
do
|
||||
Result := a_id.is_case_insensitive ("nino")
|
||||
end{/if}
|
||||
|
||||
{if condition="$WIZ.connectors.use_cgi ~ $WIZ_YES"}
|
||||
is_cgi_launcher_id (a_id: READABLE_STRING_GENERAL): BOOLEAN
|
||||
do
|
||||
|
||||
@@ -84,12 +84,10 @@ Web application runs on top of connectors
|
||||
Select connectors you want to support:
|
||||
]")
|
||||
Result.add_boolean_question ("Standalone", "use_standalone", "Using the standalone Eiffel Web server")
|
||||
Result.add_boolean_question ("Nino", "use_nino", "Using the Eiffel Web nino server")
|
||||
Result.add_boolean_question ("CGI", "use_cgi", "Require a httpd server")
|
||||
Result.add_boolean_question ("libFCGI", "use_libfcgi", "Require a httpd server")
|
||||
|
||||
Result.data.force ("yes", "use_standalone")
|
||||
Result.data.force ("no", "use_nino")
|
||||
Result.data.force ("yes", "use_cgi")
|
||||
Result.data.force ("yes", "use_libfcgi")
|
||||
end
|
||||
@@ -97,7 +95,7 @@ Select connectors you want to support:
|
||||
standalone_connector_page: WIZARD_PAGE
|
||||
once
|
||||
Result := new_page ("standalone_connector")
|
||||
Result.set_title ("Standalone (or nino) connector")
|
||||
Result.set_title ("Standalone connector")
|
||||
Result.set_subtitle ("Set options .")
|
||||
Result.add_integer_question ("Port number", "port", "It happens port 80 is already taken, thus choose another one.")
|
||||
Result.add_boolean_question ("Verbose", "verbose", "Verbose output")
|
||||
@@ -175,12 +173,6 @@ Use the filter component:
|
||||
end
|
||||
sv.append ("standalone")
|
||||
end
|
||||
if connectors_page.boolean_field_value ("use_nino") then
|
||||
if not sv.is_empty then
|
||||
sv.append (", ")
|
||||
end
|
||||
sv.append ("nino")
|
||||
end
|
||||
if connectors_page.boolean_field_value ("use_cgi") then
|
||||
if not sv.is_empty then
|
||||
sv.append (", ")
|
||||
@@ -221,7 +213,6 @@ feature -- Events
|
||||
elseif a_current_page = connectors_page then
|
||||
if
|
||||
connectors_page.boolean_field_value ("use_standalone")
|
||||
or connectors_page.boolean_field_value ("use_nino")
|
||||
then
|
||||
Result := standalone_connector_page
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user