Compare commits

...

17 Commits

Author SHA1 Message Date
13ad524a03 Fixed httpd and http_network ecf in non void-safe mode. 2016-10-18 14:23:58 +02:00
d28f794828 Implemented chunked Transfer-Encoding in net_http_client.
Implemented support for buffer_size and chunk_size for net_http_client.
2016-10-12 16:49:08 +02:00
9e92b8c0fa Fixed typo in restbuck name. 2016-10-12 11:21:42 +02:00
ef704790a8 Fixed the "wsf_tests" autocase suite, which was wrong for cookies, and other minor changes. 2016-10-12 11:21:27 +02:00
57b1691243 Added support for debug.ini to debug example. 2016-10-12 11:19:54 +02:00
29590b1c0d Fixed potential issue related to PATH_INFO, and percent_encoded_path_info computing , when script name is in different path. 2016-10-12 11:19:23 +02:00
ed959042d7 Fixed issue with input using "Transfer-Encoding: chunked". 2016-10-12 11:12:37 +02:00
1170417e54 Fixed regression with persistent connection, be sure to keep the remote_info data for all successive requests within a same persistent connection. 2016-10-11 17:34:07 +02:00
2cfe00e61b Updated desktop_app example with embedded standalone web server. 2016-10-11 17:30:50 +02:00
a498a167ed Updated desktop application example for scoop concurrency mode. 2016-10-11 16:20:04 +02:00
f12158e535 Use the ..._noexception network features in the WGI standalone input and output classes. 2016-10-11 10:57:05 +02:00
080881368a Also check for SOCKET.was_error when accessing the socket data. 2016-10-11 10:29:38 +02:00
Jocelyn Fiat
3e935c7e33 Use `was_error' to get expected behavior on Linux. 2016-10-10 22:27:45 +02:00
Jocelyn Fiat
ad2bb0d1a7 Fixed C compilation on non Windows platform for EiffelStudio until 16.05 .
(the required c function are coming with EiffelNet from EiffelStudio 16.11 ).
2016-10-10 22:17:41 +02:00
7a546622bc Updated deprecated EiffelWeb nino to make it compilable with upcoming EiffelStudio 16.11.
Updated various projects to make them up-to-date and compilable with this latest EiffelWeb.
2016-10-10 21:40:15 +02:00
aed7461faf Improved networking implementation for httpd server and sockets.
Use new EiffelNet routines that do not raise exception on error.
Made compilable with 16.05 and dev-and-upcoming release 16.11.
Fixed various minor issues related to base_url, and added comments.
2016-10-08 01:10:16 +02:00
56819d6793 Replace Nino by Standalone whenever it is relevant. 2016-10-08 01:02:12 +02:00
101 changed files with 1667 additions and 1363 deletions

View File

@@ -17,10 +17,21 @@ create
make_server_by_port make_server_by_port
create {NETWORK_STREAM_SOCKET} create {NETWORK_STREAM_SOCKET}
make_from_descriptor_and_address make_from_descriptor_and_address,
make_empty
feature {NONE} -- Initialization 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 make
-- Create a network stream socket. -- Create a network stream socket.
do do
@@ -28,16 +39,6 @@ feature {NONE} -- Initialization
set_reuse_address 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
feature -- Basic operation feature -- Basic operation
send_message (a_msg: STRING) send_message (a_msg: STRING)

View File

@@ -29,16 +29,6 @@ feature {NONE} -- Initialization
set_reuse_address 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
feature -- Basic operation feature -- Basic operation
send_message (a_msg: STRING) send_message (a_msg: STRING)

View File

@@ -22,13 +22,13 @@
<file_rule> <file_rule>
<exclude>tcp_stream_socket.e</exclude> <exclude>tcp_stream_socket.e</exclude>
<condition> <condition>
<version type="compiler" max="15.01.9.6506"/> <version type="compiler" max="16.11"/>
</condition> </condition>
</file_rule> </file_rule>
</cluster> </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> <condition>
<version type="compiler" max="15.01.9.6506"/> <version type="compiler" max="16.11"/>
</condition> </condition>
</cluster> </cluster>
</target> </target>

View File

@@ -1,35 +1,35 @@
<?xml version="1.0" encoding="ISO-8859-1"?> <?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"> <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"> <target name="nino">
<root all_classes="true"/> <root all_classes="true"/>
<file_rule> <file_rule>
<exclude>/.git$</exclude> <exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude> <exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude> <exclude>/CVS$</exclude>
<exclude>/.svn$</exclude> <exclude>/.svn$</exclude>
</file_rule> </file_rule>
<option warning="true" void_safety="none"> <option warning="true" void_safety="none">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </option>
<setting name="concurrency" value="thread"/> <setting name="concurrency" value="thread"/>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="net" location="$ISE_LIBRARY\library\net\net.ecf"/> <library name="net" location="$ISE_LIBRARY\library\net\net.ecf"/>
<library name="thread" location="$ISE_LIBRARY\library\thread\thread.ecf"/> <library name="thread" location="$ISE_LIBRARY\library\thread\thread.ecf"/>
<cluster name="nino" location=".\library\" recursive="true"> <cluster name="nino" location=".\library\" recursive="true">
<file_rule> <file_rule>
<exclude>spec</exclude> <exclude>spec</exclude>
</file_rule> </file_rule>
<file_rule> <file_rule>
<exclude>tcp_stream_socket.e</exclude> <exclude>tcp_stream_socket.e</exclude>
<condition> <condition>
<version type="compiler" max="15.01.9.6506"/> <version type="compiler" max="16.11"/>
</condition> </condition>
</file_rule> </file_rule>
</cluster> </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> <condition>
<version type="compiler" max="15.01.9.6506"/> <version type="compiler" max="16.11"/>
</condition> </condition>
</cluster> </cluster>
</target> </target>
</system> </system>

View File

@@ -1,22 +1,29 @@
The main goal of the connectors is to let you choose a target at compile time. 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. 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: The current connectors are:
* Nino * Standalone
* FastCGI * FastCGI
* CGI * CGI
* OpenShift * 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. The most widely used workflow is to use Standalone 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. 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! 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. 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. 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). 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 # FastCGI

View File

@@ -61,7 +61,7 @@ Using EWF, your service is built on top of underlying httpd solution/connectors.
Currently 3 main connectors are available: Currently 3 main connectors are available:
* __CGI__: following the CGI interface, this is an easy solution to run the service on any platform. * __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, ... * __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. 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 It is fairly easy to add new connector, it just has to follow the EWSGI interface

View File

@@ -4,7 +4,7 @@ Now you have to implement each handler. You need to inherit from WSF_SKELETON_HA
## Communicating between routines ## 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: Internally, the framework uses the following execution variable names, so you must avoid them:
1. REQUEST_ENTITY 1. REQUEST_ENTITY

View File

@@ -59,7 +59,7 @@ feature -- Basic operations
end 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). 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. 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.
![Launcher Hierarchy](./Launcher Hierarchy.png "Launcher Hierarchy") ![Launcher Hierarchy](./Launcher Hierarchy.png "Launcher Hierarchy")
@@ -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``` ```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> <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``` ```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) Nav: [Workbook](../workbook.md) :: [Handling Requests: Form/Query Parameter](../handling_request/form.md)

View File

@@ -13,14 +13,6 @@
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/> <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"/> <library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
</target> </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"> <target name="simple_cgi" extends="common">
<root class="APPLICATION" feature="make_and_launch"/> <root class="APPLICATION" feature="make_and_launch"/>
<option warning="true" is_attached_by_default="true" void_safety="transitional" syntax="transitional"> <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"/> <library name="default_standalone" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\standalone-safe.ecf"/>
<cluster name="simple" location=".\" recursive="true"/> <cluster name="simple" location=".\" recursive="true"/>
</target> </target>
<target name="simple" extends="simple_nino"> <target name="simple" extends="simple_standalone">
</target> </target>
</system> </system>

View File

@@ -13,12 +13,12 @@
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/> <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"/> <library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
</target> </target>
<target name="simple_html_nino" extends="common"> <target name="simple_html_standalone" extends="common">
<root class="APPLICATION" feature="make_and_launch"/> <root class="APPLICATION" feature="make_and_launch"/>
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional"> <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"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </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"/> <cluster name="simple_html" location=".\" recursive="true"/>
</target> </target>
<target name="simple_html_cgi" extends="common"> <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"/> <library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
<cluster name="simple_html" location=".\" recursive="true"/> <cluster name="simple_html" location=".\" recursive="true"/>
</target> </target>
<target name="simple_html" extends="simple_html_nino"> <target name="simple_html" extends="simple_html_standalone">
</target> </target>
</system> </system>

View File

@@ -13,12 +13,12 @@
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/> <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"/> <library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
</target> </target>
<target name="exel_nino" extends="common"> <target name="exel_standalone" extends="common">
<root class="APPLICATION" feature="make_and_launch"/> <root class="APPLICATION" feature="make_and_launch"/>
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional"> <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"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </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"/> <cluster name="exel" location=".\" recursive="true"/>
</target> </target>
<target name="exel_cgi" extends="common"> <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"/> <library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
<cluster name="exel" location=".\" recursive="true"/> <cluster name="exel" location=".\" recursive="true"/>
</target> </target>
<target name="exel" extends="exel_nino"> <target name="exel" extends="exel_standalone">
</target> </target>
</system> </system>

View File

@@ -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"> <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"> <target name="common" abstract="true">
<file_rule> <file_rule>
@@ -13,12 +13,12 @@
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/> <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"/> <library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
</target> </target>
<target name="headers_nino" extends="common"> <target name="headers_standalone" extends="common">
<root class="APPLICATION" feature="make_and_launch"/> <root class="APPLICATION" feature="make_and_launch"/>
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional"> <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"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </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"/> <cluster name="headers" location=".\" recursive="true"/>
</target> </target>
<target name="headers_cgi" extends="common"> <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"/> <library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
<cluster name="headers" location=".\" recursive="true"/> <cluster name="headers" location=".\" recursive="true"/>
</target> </target>
<target name="headers" extends="headers_nino"> <target name="headers" extends="headers_standalone">
</target> </target>
</system> </system>

View File

@@ -13,12 +13,12 @@
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/> <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"/> <library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
</target> </target>
<target name="search_nino" extends="common"> <target name="search_standalone" extends="common">
<root class="APPLICATION" feature="make_and_launch"/> <root class="APPLICATION" feature="make_and_launch"/>
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional"> <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"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </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"/> <cluster name="search" location=".\" recursive="true"/>
</target> </target>
<target name="search_cgi" extends="common"> <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"/> <library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
<cluster name="search" location=".\" recursive="true"/> <cluster name="search" location=".\" recursive="true"/>
</target> </target>
<target name="search" extends="search_nino"> <target name="search" extends="search_standalone">
</target> </target>
</system> </system>

View File

@@ -13,12 +13,12 @@
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/> <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"/> <library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
</target> </target>
<target name="status_nino" extends="common"> <target name="status_standalone" extends="common">
<root class="APPLICATION" feature="make_and_launch"/> <root class="APPLICATION" feature="make_and_launch"/>
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional"> <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"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </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"/> <cluster name="status" location=".\" recursive="true"/>
</target> </target>
<target name="status_cgi" extends="common"> <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"/> <library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
<cluster name="status" location=".\" recursive="true"/> <cluster name="status" location=".\" recursive="true"/>
</target> </target>
<target name="status" extends="status_nino"> <target name="status" extends="status_standalone">
</target> </target>
</system> </system>

View File

@@ -13,12 +13,12 @@
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/> <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"/> <library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
</target> </target>
<target name="example_nino" extends="common"> <target name="example_standalone" extends="common">
<root class="APPLICATION" feature="make_and_launch"/> <root class="APPLICATION" feature="make_and_launch"/>
<option warning="true" is_attached_by_default="true" void_safety="transitional" syntax="transitional"> <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"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </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"/> <cluster name="example" location=".\" recursive="true"/>
</target> </target>
<target name="example_cgi" extends="common"> <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"/> <library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
<cluster name="example" location=".\" recursive="true"/> <cluster name="example" location=".\" recursive="true"/>
</target> </target>
<target name="example" extends="example_nino"> <target name="example" extends="example_standalone">
</target> </target>
</system> </system>

View File

@@ -13,12 +13,12 @@
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/> <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"/> <library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
</target> </target>
<target name="form_nino" extends="common"> <target name="form_standalone" extends="common">
<root class="APPLICATION" feature="make_and_launch"/> <root class="APPLICATION" feature="make_and_launch"/>
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional"> <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"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </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"/> <cluster name="form" location=".\" recursive="true"/>
</target> </target>
<target name="form_cgi" extends="common"> <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"/> <library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
<cluster name="form" location=".\" recursive="true"/> <cluster name="form" location=".\" recursive="true"/>
</target> </target>
<target name="form" extends="form_nino"> <target name="form" extends="form_standalone">
</target> </target>
</system> </system>

View File

@@ -13,12 +13,12 @@
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/> <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"/> <library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
</target> </target>
<target name="form_nino" extends="common"> <target name="form_standalone" extends="common">
<root class="APPLICATION" feature="make_and_launch"/> <root class="APPLICATION" feature="make_and_launch"/>
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional"> <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"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </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"/> <cluster name="form" location=".\" recursive="true"/>
</target> </target>
<target name="form_cgi" extends="common"> <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"/> <library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
<cluster name="form" location=".\" recursive="true"/> <cluster name="form" location=".\" recursive="true"/>
</target> </target>
<target name="form" extends="form_nino"> <target name="form" extends="form_standalone">
</target> </target>
</system> </system>

View File

@@ -13,12 +13,12 @@
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/> <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"/> <library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
</target> </target>
<target name="browsers_nino" extends="common"> <target name="browsers_standalone" extends="common">
<root class="APPLICATION" feature="make_and_launch"/> <root class="APPLICATION" feature="make_and_launch"/>
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional"> <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"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </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"/> <cluster name="browsers" location=".\" recursive="true"/>
</target> </target>
<target name="browsers_cgi" extends="common"> <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"/> <library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
<cluster name="browsers" location=".\" recursive="true"/> <cluster name="browsers" location=".\" recursive="true"/>
</target> </target>
<target name="browsers" extends="browsers_nino"> <target name="browsers" extends="browsers_standalone">
</target> </target>
</system> </system>

View File

@@ -13,12 +13,12 @@
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/> <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"/> <library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
</target> </target>
<target name="cgi_variables_nino" extends="common"> <target name="cgi_variables_standalone" extends="common">
<root class="APPLICATION" feature="make_and_launch"/> <root class="APPLICATION" feature="make_and_launch"/>
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional"> <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"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </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"/> <cluster name="cgi_variables" location=".\" recursive="true"/>
</target> </target>
<target name="cgi_variables_cgi" extends="common"> <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"/> <library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
<cluster name="cgi_variables" location=".\" recursive="true"/> <cluster name="cgi_variables" location=".\" recursive="true"/>
</target> </target>
<target name="cgi_variables" extends="cgi_variables_nino"> <target name="cgi_variables" extends="cgi_variables_standalone">
</target> </target>
</system> </system>

View File

@@ -13,12 +13,12 @@
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/> <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"/> <library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
</target> </target>
<target name="header_fields_nino" extends="common"> <target name="header_fields_standalone" extends="common">
<root class="APPLICATION" feature="make_and_launch"/> <root class="APPLICATION" feature="make_and_launch"/>
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional"> <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"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </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"/> <cluster name="header_fields" location=".\" recursive="true"/>
</target> </target>
<target name="header_fields_cgi" extends="common"> <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"/> <library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
<cluster name="header_fields" location=".\" recursive="true"/> <cluster name="header_fields" location=".\" recursive="true"/>
</target> </target>
<target name="header_fields" extends="header_fields_nino"> <target name="header_fields" extends="header_fields_standalone">
</target> </target>
</system> </system>

View File

@@ -13,12 +13,12 @@
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/> <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"/> <library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
</target> </target>
<target name="upload_nino" extends="common"> <target name="upload_standalone" extends="common">
<root class="APPLICATION" feature="make_and_launch"/> <root class="APPLICATION" feature="make_and_launch"/>
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional"> <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"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </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"/> <cluster name="upload" location=".\" recursive="true"/>
</target> </target>
<target name="upload_cgi" extends="common"> <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"/> <library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
<cluster name="upload" location=".\" recursive="true"/> <cluster name="upload" location=".\" recursive="true"/>
</target> </target>
<target name="upload" extends="upload_nino"> <target name="upload" extends="upload_standalone">
</target> </target>
</system> </system>

View File

@@ -14,9 +14,9 @@
<library name="wsf" location="..\..\..\..\..\..\library\server\wsf\wsf-safe.ecf"/> <library name="wsf" location="..\..\..\..\..\..\library\server\wsf\wsf-safe.ecf"/>
<library name="wsf_js_widget" location="..\..\wsf_js_widget-safe.ecf" readonly="false"/> <library name="wsf_js_widget" location="..\..\wsf_js_widget-safe.ecf" readonly="false"/>
</target> </target>
<target name="js_widget_template_nino" extends="common"> <target name="js_widget_template_standalone" extends="common">
<root class="APPLICATION" feature="make_and_launch"/> <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 name="js_widget_template" location=".\src\" recursive="true">
</cluster> </cluster>
</target> </target>
@@ -30,6 +30,6 @@
<library name="default_libfcgi" location="..\..\..\..\..\..\library\server\wsf\default\libfcgi-safe.ecf"/> <library name="default_libfcgi" location="..\..\..\..\..\..\library\server\wsf\default\libfcgi-safe.ecf"/>
<cluster name="js_widget_template" location=".\src\" recursive="true"/> <cluster name="js_widget_template" location=".\src\" recursive="true"/>
</target> </target>
<target name="js_widget_template" extends="js_widget_template_nino"> <target name="js_widget_template" extends="js_widget_template_standalone">
</target> </target>
</system> </system>

View File

@@ -14,9 +14,9 @@
<library name="wsf" location="..\..\..\..\..\..\library\server\wsf\wsf-safe.ecf"/> <library name="wsf" location="..\..\..\..\..\..\library\server\wsf\wsf-safe.ecf"/>
<library name="wsf_js_widget" location="..\..\wsf_js_widget-safe.ecf" readonly="false"/> <library name="wsf_js_widget" location="..\..\wsf_js_widget-safe.ecf" readonly="false"/>
</target> </target>
<target name="js_custom_widget_nino" extends="common"> <target name="js_custom_widget_standalone" extends="common">
<root class="APPLICATION" feature="make_and_launch"/> <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 name="js_custom_widget" location=".\src\" recursive="true">
</cluster> </cluster>
</target> </target>
@@ -30,6 +30,6 @@
<library name="default_libfcgi" location="..\..\..\..\..\..\library\server\wsf\default\libfcgi-safe.ecf"/> <library name="default_libfcgi" location="..\..\..\..\..\..\library\server\wsf\default\libfcgi-safe.ecf"/>
<cluster name="js_custom_widget" location=".\src\" recursive="true"/> <cluster name="js_custom_widget" location=".\src\" recursive="true"/>
</target> </target>
<target name="js_custom_widget" extends="js_custom_widget_nino"> <target name="js_custom_widget" extends="js_custom_widget_standalone">
</target> </target>
</system> </system>

View File

@@ -16,12 +16,12 @@
<library name="wsf" location="..\..\..\..\..\..\library\server\wsf\wsf-safe.ecf"/> <library name="wsf" location="..\..\..\..\..\..\library\server\wsf\wsf-safe.ecf"/>
<library name="wsf_js_widget" location="..\..\wsf_js_widget-safe.ecf" readonly="false"/> <library name="wsf_js_widget" location="..\..\wsf_js_widget-safe.ecf" readonly="false"/>
</target> </target>
<target name="demo_nino" extends="common"> <target name="demo_standalone" extends="common">
<root class="APPLICATION" feature="make_and_launch"/> <root class="APPLICATION" feature="make_and_launch"/>
<option warning="true" is_attached_by_default="true" void_safety="transitional" syntax="transitional"> <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"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </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"/> <cluster name="demo" location=".\" recursive="true"/>
</target> </target>
<target name="demo_cgi" extends="common"> <target name="demo_cgi" extends="common">
@@ -40,6 +40,6 @@
<library name="default_libfcgi" location="..\..\..\..\..\..\library\server\wsf\default\libfcgi-safe.ecf"/> <library name="default_libfcgi" location="..\..\..\..\..\..\library\server\wsf\default\libfcgi-safe.ecf"/>
<cluster name="demo" location=".\" recursive="true"/> <cluster name="demo" location=".\" recursive="true"/>
</target> </target>
<target name="demo" extends="demo_nino"> <target name="demo" extends="demo_standalone">
</target> </target>
</system> </system>

View File

@@ -17,13 +17,13 @@
<root class="${APP_ROOT}" feature="make_and_launch"/> <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="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="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="launcher" location=".\launcher\any\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/> <cluster name="src" location=".\src\" recursive="true"/>
</target> </target>
<target name="${APPNAME}_nino" extends="common"> <target name="${APPNAME}_standalone" extends="common">
<root class="${APP_ROOT}" feature="make_and_launch"/> <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="launcher" location=".\launcher\default\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/> <cluster name="src" location=".\src\" recursive="true"/>
</target> </target>
@@ -40,6 +40,6 @@
<cluster name="src" location=".\src\" recursive="true"/> <cluster name="src" location=".\src\" recursive="true"/>
</target> </target>
<target name="${APPNAME}" extends="${APPNAME}_nino"/> <target name="${APPNAME}" extends="${APPNAME}_standalone"/>
</system> </system>

View File

@@ -2,7 +2,7 @@
<root class="${APP_ROOT}" feature="make_and_launch"/> <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="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="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="launcher" location=".\launcher\any\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/> <cluster name="src" location=".\src\" recursive="true"/>
</target> </target>

View File

@@ -22,8 +22,8 @@ feature -- Execution
nature: like launcher_nature nature: like launcher_nature
do do
nature := launcher_nature nature := launcher_nature
if nature = Void or else nature = nature_nino then if nature = Void or else nature = nature_standalone then
launch_nino (a_service, opts) launch_standalone (a_service, opts)
elseif nature = nature_cgi then elseif nature = nature_cgi then
launch_cgi (a_service, opts) launch_cgi (a_service, opts)
elseif nature = nature_libfcgi then elseif nature = nature_libfcgi then
@@ -38,7 +38,7 @@ feature {NONE} -- Access
launcher_nature: detachable READABLE_STRING_8 launcher_nature: detachable READABLE_STRING_8
-- Initialize the launcher nature -- Initialize the launcher nature
-- either cgi, libfcgi, or nino. -- either cgi, libfcgi, or standalone.
--| We could extend with more connector if needed. --| We could extend with more connector if needed.
--| and we could use WSF_DEFAULT_SERVICE_LAUNCHER to configure this at compilation time. --| and we could use WSF_DEFAULT_SERVICE_LAUNCHER to configure this at compilation time.
local local
@@ -51,8 +51,8 @@ feature {NONE} -- Access
ext := l_entry.extension ext := l_entry.extension
end end
if ext /= Void then if ext /= Void then
if ext.same_string (nature_nino) then if ext.same_string (nature_standalone) then
Result := nature_nino Result := nature_standalone
end end
if ext.same_string (nature_cgi) then if ext.same_string (nature_cgi) then
Result := nature_cgi Result := nature_cgi
@@ -63,13 +63,13 @@ feature {NONE} -- Access
end end
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 local
launcher: WSF_NINO_SERVICE_LAUNCHER launcher: WSF_STANDALONE_SERVICE_LAUNCHER
do do
create launcher.make_and_launch (a_service, opts) create launcher.make_and_launch (a_service, opts)
end end

View File

@@ -21,7 +21,6 @@
<setting name="concurrency" value="thread"/> <setting name="concurrency" value="thread"/>
<library name="cgi" location="..\..\library\server\wsf\connector\cgi-safe.ecf" readonly="false"/> <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="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"/> <library name="standalone" location="..\..\library\server\wsf\connector\standalone-safe.ecf" readonly="false"/>
<cluster name="launcher" location=".\launcher\any\" recursive="true"/> <cluster name="launcher" location=".\launcher\any\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/> <cluster name="src" location=".\src\" recursive="true"/>
@@ -33,12 +32,6 @@
<cluster name="launcher" location=".\launcher\default\" recursive="true"/> <cluster name="launcher" location=".\launcher\default\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/> <cluster name="src" location=".\src\" recursive="true"/>
</target> </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"> <target name="debug_cgi" extends="common">
<root class="EWF_DEBUG_SERVER" feature="make_and_launch"/> <root class="EWF_DEBUG_SERVER" feature="make_and_launch"/>
<library name="default_cgi" location="..\..\library\server\wsf\default\cgi-safe.ecf" readonly="false"/> <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="launcher" location=".\launcher\default\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/> <cluster name="src" location=".\src\" recursive="true"/>
</target> </target>
<target name="debug" extends="debug_nino"> <target name="debug" extends="debug_standalone">
</target> </target>
</system> </system>

View File

@@ -24,8 +24,6 @@ feature -- Execution
nature := launcher_nature nature := launcher_nature
if nature = Void or else nature = nature_standalone then if nature = Void or else nature = nature_standalone then
launch_standalone (opts) launch_standalone (opts)
elseif nature = nature_nino then
launch_nino (opts)
elseif nature = nature_cgi then elseif nature = nature_cgi then
launch_cgi (opts) launch_cgi (opts)
elseif nature = nature_libfcgi then elseif nature = nature_libfcgi then
@@ -40,7 +38,7 @@ feature {NONE} -- Access
launcher_nature: detachable READABLE_STRING_8 launcher_nature: detachable READABLE_STRING_8
-- Initialize the launcher nature -- Initialize the launcher nature
-- either cgi, libfcgi, or nino. -- either cgi, libfcgi, or standalone.
--| We could extend with more connector if needed. --| We could extend with more connector if needed.
--| and we could use WSF_DEFAULT_SERVICE_LAUNCHER to configure this at compilation time. --| and we could use WSF_DEFAULT_SERVICE_LAUNCHER to configure this at compilation time.
local local
@@ -55,9 +53,6 @@ feature {NONE} -- Access
if ext.same_string (nature_standalone) then if ext.same_string (nature_standalone) then
Result := nature_standalone Result := nature_standalone
end end
if ext.same_string (nature_nino) then
Result := nature_nino
end
if ext.same_string (nature_cgi) then if ext.same_string (nature_cgi) then
Result := nature_cgi Result := nature_cgi
end end
@@ -68,7 +63,7 @@ feature {NONE} -- Access
Result := nature_standalone Result := nature_standalone
end end
feature {NONE} -- nino feature {NONE} -- Standalone
nature_standalone: STRING = "standalone" nature_standalone: STRING = "standalone"
@@ -79,17 +74,6 @@ feature {NONE} -- nino
create launcher.make_and_launch (opts) create launcher.make_and_launch (opts)
end 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 feature {NONE} -- cgi
nature_cgi: STRING = "cgi" nature_cgi: STRING = "cgi"

View File

@@ -28,6 +28,7 @@ feature {NONE} -- Initialization
-- set_service_option ("verbose", True) -- set_service_option ("verbose", True)
set_service_option ("port", 9090) set_service_option ("port", 9090)
-- set_service_option ("base", "/www-debug/debug_service.fcgi/") -- set_service_option ("base", "/www-debug/debug_service.fcgi/")
import_service_options (create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI}.make_from_file ("debug.ini"))
end end
-- execute (req: WSF_REQUEST; res: WSF_RESPONSE) -- execute (req: WSF_REQUEST; res: WSF_RESPONSE)

View File

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

View File

@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="ISO-8859-1"?> <?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="desktop_app" uuid="E015841A-D456-46E1-8A18-E0CEB9E69CD5"> <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="desktop_app" uuid="E015841A-D456-46E1-8A18-E0CEB9E69CD5">
<description>Vision2+web browser widget+embedded web service</description> <description>Vision2+web browser widget+embedded web service</description>
<target name="desktop_app"> <target name="desktop_app">
<description>This example demonstrates how to build a vision2 desktop application that embed a web browser accessing the service of an embedded web service.</description> <description>This example demonstrates how to build a vision2 desktop application that embed a web browser accessing the service of an embedded web service.</description>
<root class="DESKTOP_APP" feature="make_and_launch"/> <root class="DESKTOP_APP" feature="make_and_launch"/>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="transitional" syntax="transitional"> <option warning="true" full_class_checking="true" is_attached_by_default="true" is_obsolete_routine_type="true" void_safety="all" syntax="transitional">
<assertions precondition="true" postcondition="true" check="true"/> <assertions precondition="true" postcondition="true" check="true"/>
</option> </option>
<setting name="concurrency" value="thread"/> <setting name="concurrency" value="scoop"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="ewsgi" location="..\..\library\server\ewsgi\ewsgi-safe.ecf"/> <library name="ewsgi" location="..\..\library\server\ewsgi\ewsgi-safe.ecf"/>
<library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/> <library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
@@ -18,9 +18,9 @@
<library name="wsf_standalone_connector" location="..\..\library\server\ewsgi\connectors\standalone\standalone-safe.ecf"/> <library name="wsf_standalone_connector" location="..\..\library\server\ewsgi\connectors\standalone\standalone-safe.ecf"/>
<cluster name="src" location=".\src\" recursive="true"> <cluster name="src" location=".\src\" recursive="true">
<file_rule> <file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude> <exclude>/.svn$</exclude>
<exclude>/CVS$</exclude>
<exclude>/EIFGENs$</exclude>
</file_rule> </file_rule>
</cluster> </cluster>
</target> </target>

View File

@@ -24,20 +24,25 @@ feature {NONE} -- Initialization
-- then launch the application. -- then launch the application.
local local
l_win: like main_window l_win: like main_window
l_embedded_service: APP_EMBEDDED_WEB_SERVICE l_embedded_service: separate APP_EMBEDDED_WEB_SERVICE
do do
default_create default_create
create l_win.make create l_win.make
main_window := l_win main_window := l_win
l_win.show l_win.show
create l_embedded_service.make create l_embedded_service.make
l_embedded_service.set_port_number (0) -- Use first available port number setup_and_launch_web_service (l_embedded_service)
l_embedded_service.on_launched_actions.force (agent on_web_service_launched (l_win, l_embedded_service))
l_embedded_service.launch
launch launch
end end
setup_and_launch_web_service (a_web_service: separate APP_EMBEDDED_WEB_SERVICE)
do
a_web_service.set_port_number (0) -- Use first available port number
a_web_service.set_on_launched_action (agent on_web_service_launched (a_web_service))
a_web_service.launch
end
on_quit on_quit
do do
if attached main_window as win then if attached main_window as win then
@@ -45,13 +50,15 @@ feature {NONE} -- Initialization
end end
end end
on_web_service_launched (a_win: attached like main_window; s: APP_EMBEDDED_WEB_SERVICE) on_web_service_launched (a_web_service: separate APP_EMBEDDED_WEB_SERVICE)
do do
add_idle_action_kamikaze (agent wait_for_termination (s, Void)) if attached main_window as win then
add_idle_action_kamikaze (agent a_win.open_link) add_idle_action_kamikaze (agent wait_for_termination (a_web_service, Void))
add_idle_action_kamikaze (agent win.open_link)
end
end end
wait_for_termination (s: APP_EMBEDDED_WEB_SERVICE; a_timeout: detachable EV_TIMEOUT) wait_for_termination (a_web_service: separate APP_EMBEDDED_WEB_SERVICE; a_timeout: detachable EV_TIMEOUT)
local local
t: detachable EV_TIMEOUT t: detachable EV_TIMEOUT
do do
@@ -60,7 +67,7 @@ feature {NONE} -- Initialization
t.set_interval (0) t.set_interval (0)
end end
if if
attached s.observer as obs and then attached a_web_service.observer as obs and then
observer_has_terminaded (obs) observer_has_terminaded (obs)
then then
if t /= Void then if t /= Void then
@@ -70,7 +77,7 @@ feature {NONE} -- Initialization
else else
if t = Void then if t = Void then
create t create t
t.actions.extend (agent wait_for_termination (s, t)) t.actions.extend (agent wait_for_termination (a_web_service, t))
else else
t.set_interval (1_000) t.set_interval (1_000)
end end

View File

@@ -17,19 +17,21 @@ inherit
feature {NONE} -- Execution feature {NONE} -- Execution
execute_embedded execute_embedded
-- Execute the request -- Execute the request
-- See `request.input' for input stream -- See `request.input' for input stream
-- `request.meta_variables' for the CGI meta variable -- `request.meta_variables' for the CGI meta variable
-- and `response' for output buffer -- and `response' for output buffer
local local
filter: WSF_AGENT_FILTER
m: WSF_PAGE_RESPONSE m: WSF_PAGE_RESPONSE
do do
if local_connection_restriction_enabled then if local_connection_restriction_enabled then
if if
attached request.remote_addr as l_remote_addr and then attached request.remote_addr as l_remote_addr and then
l_remote_addr.is_case_insensitive_equal_general ("127.0.0.1") (
l_remote_addr.is_case_insensitive_equal_general ("127.0.0.1")
or else l_remote_addr.is_case_insensitive_equal_general ("localhost")
)
then then
execute execute
else else
@@ -41,7 +43,7 @@ feature {NONE} -- Execution
execute execute
end end
end end
execute execute
deferred deferred
end end

View File

@@ -16,7 +16,6 @@ feature -- Initialization
make make
do do
create on_launched_actions
end end
feature -- Execution feature -- Execution
@@ -27,7 +26,6 @@ feature -- Execution
opts: WSF_SERVICE_LAUNCHER_OPTIONS opts: WSF_SERVICE_LAUNCHER_OPTIONS
do do
create opts.default_create create opts.default_create
opts.set_verbose (True)
opts.set_option ("port", port_number) opts.set_option ("port", port_number)
create launcher.make (opts) create launcher.make (opts)
observer := launcher.connector.observer observer := launcher.connector.observer
@@ -40,11 +38,23 @@ feature -- Execution
on_launched (conn: WGI_STANDALONE_CONNECTOR [G]) on_launched (conn: WGI_STANDALONE_CONNECTOR [G])
do do
set_port_number (conn.port) set_port_number (conn.port)
on_launched_actions.call (Void) if attached on_launched_action as act then
call_action (act)
end
end
call_action (act: attached like on_launched_action)
do
act.call (Void)
end end
feature -- Access feature -- Access
on_launched_actions: ACTION_SEQUENCE [TUPLE] on_launched_action: detachable separate PROCEDURE [ANY, TUPLE]
set_on_launched_action (act: like on_launched_action)
do
on_launched_action := act
end
end end

View File

@@ -7,7 +7,6 @@
<exclude>/\.svn$</exclude> <exclude>/\.svn$</exclude>
</file_rule> </file_rule>
<option debug="true" warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="transitional" syntax="provisional"> <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"/> <assertions precondition="true" postcondition="true" invariant="true" supplier_precondition="true"/>
</option> </option>
<setting name="concurrency" value="thread"/> <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_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"/> <library name="wsf_router_context" location="..\..\library\server\wsf\wsf_router_context-safe.ecf" readonly="true"/>
</target> </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"> <target name="filter_standalone" extends="common">
<root class="FILTER_SERVER" feature="make"/> <root class="FILTER_SERVER" feature="make"/>
<setting name="concurrency" value="thread"/> <setting name="concurrency" value="thread"/>
@@ -36,6 +30,6 @@
<library name="default_libfcgi" location="..\..\library\server\wsf\default\libfcgi-safe.ecf"/> <library name="default_libfcgi" location="..\..\library\server\wsf\default\libfcgi-safe.ecf"/>
<cluster name="filter" location="src\" recursive="true"/> <cluster name="filter" location="src\" recursive="true"/>
</target> </target>
<target name="filter" extends="filter_nino"> <target name="filter" extends="filter_standalone">
</target> </target>
</system> </system>

View File

@@ -25,7 +25,7 @@ Note: <br/>
RESTBUCKS_SERVER 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). 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 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 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 URI_TEMPLATE_ROUTED_SERVICE
DEFAULT_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). -- but it's possible to use other connector (CGI or FCGI).
create create

View File

@@ -12,7 +12,6 @@ Currently, 4 connectors are available within EWF (but others are available outsi
*­ CGI: the common CGI application (apache, iis, ...) *­ CGI: the common CGI application (apache, iis, ...)
* FastCGI: on any server supporting libfcgi handling (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. * 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. 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.

View File

@@ -13,7 +13,7 @@
</option> </option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="wsf" location="..\..\..\..\..\..\library\server\wsf\wsf-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=".\"/> <cluster name="src" location=".\"/>
</target> </target>

View File

@@ -27,7 +27,7 @@ feature {NONE} -- Initialization
--| Uncomment the following line, to be able to load options from the file ewf.ini --| 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") -- 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 --| so that the server listens on port 9999
--| quite often the port 80 is already busy --| quite often the port 80 is already busy
set_service_option ("port", 9999) set_service_option ("port", 9999)

View File

@@ -1,4 +1,4 @@
# For nino connector, use port 9999 # For Standalone connector, use port 9999
port=9999 port=9999
#verbose=true #verbose=true

View File

@@ -28,7 +28,7 @@ feature {NONE} -- Initialization
--| Uncomment the following line, to be able to load options from the file ewf.ini --| 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") 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 --| so that the server listens on port 9999
--| quite often the port 80 is already busy --| quite often the port 80 is already busy
-- set_service_option ("port", 9999) -- set_service_option ("port", 9999)

View File

@@ -1,4 +1,4 @@
# For nino connector, use port 9999 # For standalone connector, use port 9999
port=9999 port=9999
#verbose=true #verbose=true

View File

@@ -22,7 +22,7 @@ feature {NONE} -- Initialization
make make
-- Initialize Current -- Initialize Current
do 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 -- Uncomment the following line
set_service_option ("port", 9090) set_service_option ("port", 9090)
make_and_launch make_and_launch

View File

@@ -20,10 +20,13 @@
</target> </target>
<target name="upload_image_standalone" extends="upload_image_common"> <target name="upload_image_standalone" extends="upload_image_common">
<root class="IMAGE_UPLOADER" feature="make"/> <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"/> <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"/> <cluster name="src" location="src\" recursive="true"/>
</target> </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"> <target name="upload_image_libfcgi" extends="upload_image_common">
<root class="IMAGE_UPLOADER" feature="make"/> <root class="IMAGE_UPLOADER" feature="make"/>
<setting name="concurrency" value="none"/> <setting name="concurrency" value="none"/>

View File

@@ -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 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-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 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 standalone-safe : C:\_dev\projects\ewf\ewf\library\server\ewsgi\connectors\standalone\standalone-safe.ecf
nino : C:\_dev\projects\ewf\ewf\library\server\ewsgi\connectors\nino\nino.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-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 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 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 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-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 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 standalone-safe : C:\_dev\projects\ewf\ewf\library\server\wsf\connector\standalone-safe.ecf
nino : C:\_dev\projects\ewf\ewf\library\server\wsf\connector\nino.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 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-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 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-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 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 standalone-safe : C:\_dev\projects\ewf\ewf\library\server\wsf\default\standalone-safe.ecf
nino : C:\_dev\projects\ewf\ewf\library\server\wsf\default\nino.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 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-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 wsf_html : C:\_dev\projects\ewf\ewf\library\server\wsf_html\wsf_html.ecf

View File

@@ -164,11 +164,24 @@ feature -- Settings
Result := session.ignore_content_length Result := session.ignore_content_length
end end
buffer_size: NATURAL buffer_size: INTEGER
-- Set the buffer size for request. This option will -- Buffer size for request,
-- only be set if buffer_size is positive -- initialized from the session buffer_size value, or default 2_048.
do do
Result := session.buffer_size Result := session.buffer_size.to_integer_32
if Result <= 0 then
Result := 2_048
end
end
chunk_size: INTEGER
-- Chunk size for request, when "Transfer-Encoding: chunked"
-- initialized from the session buffer_size value, or default 2_048.
do
Result := session.chunk_size.to_integer_32
if Result <= 0 then
Result := 2_048
end
end end
default_response_charset: detachable READABLE_STRING_8 default_response_charset: detachable READABLE_STRING_8
@@ -249,7 +262,7 @@ feature {NONE} -- Utilities: encoding
end end
note 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)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -243,9 +243,13 @@ feature -- Settings
ignore_content_length: BOOLEAN ignore_content_length: BOOLEAN
-- Does this session ignore Content-Size headers? -- Does this session ignore Content-Size headers?
buffer_size: NATURAL buffer_size: NATURAL assign set_buffer_size
-- Set the buffer size for request. This option will -- Set the buffer size for request. This option will
-- only be set if buffer_size is positive -- only be set if buffer_size > 0.
chunk_size: NATURAL assign set_chunk_size
-- Set the chunk size for request, when "Transfer-Encoding: chunked".
-- This option will only be set if chunk_size > 0.
default_response_charset: detachable READABLE_STRING_8 default_response_charset: detachable READABLE_STRING_8
-- Default encoding of responses. Used if no charset is provided by the host. -- Default encoding of responses. Used if no charset is provided by the host.
@@ -405,8 +409,18 @@ feature -- Element change
end end
end end
set_buffer_size (a_size: like buffer_size)
do
buffer_size := a_size
end
set_chunk_size (a_size: like chunk_size)
do
chunk_size := a_size
end
note 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)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -100,6 +100,7 @@ feature -- Access
l_boundary: READABLE_STRING_8 l_boundary: READABLE_STRING_8
l_is_http_1_0_request: BOOLEAN l_is_http_1_0_request: BOOLEAN
l_is_keep_alive: BOOLEAN l_is_keep_alive: BOOLEAN
l_is_chunked_transfer_encoding: BOOLEAN
retried: BOOLEAN retried: BOOLEAN
do do
if not retried then if not retried then
@@ -179,6 +180,8 @@ feature -- Access
end end
-- handle sending data -- handle sending data
l_is_chunked_transfer_encoding := attached headers.item ("Transfer-Encoding") as l_transfer_encoding and then l_transfer_encoding.same_string ("chunked")
if ctx /= Void then if ctx /= Void then
if ctx.has_upload_filename then if ctx.has_upload_filename then
l_upload_filename := ctx.upload_filename l_upload_filename := ctx.upload_filename
@@ -195,14 +198,21 @@ feature -- Access
headers.extend ("application/x-www-form-urlencoded", "Content-Type") headers.extend ("application/x-www-form-urlencoded", "Content-Type")
l_upload_data := ctx.form_parameters_to_url_encoded_string l_upload_data := ctx.form_parameters_to_url_encoded_string
headers.force (l_upload_data.count.out, "Content-Length") headers.force (l_upload_data.count.out, "Content-Length")
if l_is_chunked_transfer_encoding then
else -- Discard chunked transfer encoding
headers.remove ("Transfer-Encoding")
l_is_chunked_transfer_encoding := False
end
elseif l_form_data /= Void then
-- create form using multipart/form-data encoding -- create form using multipart/form-data encoding
l_boundary := new_mime_boundary l_boundary := new_mime_boundary (l_form_data)
headers.extend ("multipart/form-data; boundary=" + l_boundary, "Content-Type") headers.extend ("multipart/form-data; boundary=" + l_boundary, "Content-Type")
if l_form_data /= Void then l_upload_data := form_date_and_uploaded_files_to_mime_string (l_form_data, l_upload_filename, l_boundary)
l_upload_data := form_date_and_uploaded_files_to_mime_string (l_form_data, l_upload_filename, l_boundary) headers.extend (l_upload_data.count.out, "Content-Length")
headers.extend (l_upload_data.count.out, "Content-Length") if l_is_chunked_transfer_encoding then
-- Discard chunked transfer encoding
headers.remove ("Transfer-Encoding")
l_is_chunked_transfer_encoding := False
end end
end end
elseif l_upload_data /= Void then elseif l_upload_data /= Void then
@@ -210,12 +220,16 @@ feature -- Access
if not headers.has ("Content-Type") then if not headers.has ("Content-Type") then
headers.extend ("application/x-www-form-urlencoded", "Content-Type") headers.extend ("application/x-www-form-urlencoded", "Content-Type")
end end
headers.extend (l_upload_data.count.out, "Content-Length") if not l_is_chunked_transfer_encoding then
headers.extend (l_upload_data.count.out, "Content-Length")
end
elseif l_upload_filename /= Void then elseif l_upload_filename /= Void then
check ctx.has_upload_filename end check ctx.has_upload_filename end
create l_upload_file.make_with_name (l_upload_filename) create l_upload_file.make_with_name (l_upload_filename)
if l_upload_file.exists and then l_upload_file.readable then if l_upload_file.exists and then l_upload_file.readable then
headers.extend (l_upload_file.count.out, "Content-Length") if not l_is_chunked_transfer_encoding then
headers.extend (l_upload_file.count.out, "Content-Length")
end
end end
check l_upload_file /= Void end check l_upload_file /= Void end
end end
@@ -289,12 +303,7 @@ feature -- Access
--| End of client header. --| End of client header.
s.append (Http_end_of_header_line) s.append (Http_end_of_header_line)
if l_upload_data /= Void then --| Note that any remaining data or file to upload will be done directly via the socket
s.append (l_upload_data)
s.append (http_end_of_header_line)
end
--| Note that any remaining file to upload will be done directly via the socket
--| to optimize memory usage --| to optimize memory usage
@@ -315,9 +324,20 @@ feature -- Access
end end
l_socket.put_string (s) l_socket.put_string (s)
--| Send remaining payload data, if needed. --| Send remaining payload data, if needed.
if l_upload_data /= Void then
if l_is_chunked_transfer_encoding then
put_string_using_chunked_transfer_encoding (l_upload_data, chunk_size, l_socket)
else
l_socket.put_string (l_upload_data)
end
end
if l_upload_file /= Void then if l_upload_file /= Void then
-- i.e: not yet processed if l_is_chunked_transfer_encoding then
append_file_content_to_socket (l_upload_file, l_upload_file.count, l_socket) -- i.e: not yet processed
append_file_content_to_socket_using_chunked_transfer_encoding (l_upload_file, l_upload_file.count, chunk_size, l_socket)
else
append_file_content_to_socket (l_upload_file, l_upload_file.count, l_socket)
end
end end
--|-------------------------|-- --|-------------------------|--
@@ -498,8 +518,85 @@ feature {NONE} -- Helpers
Result := utf.utf_32_string_to_utf_8_string_8 (s) Result := utf.utf_32_string_to_utf_8_string_8 (s)
end end
append_file_content_to_socket (a_file: FILE; a_len: INTEGER; a_output: NETWORK_STREAM_SOCKET) put_string_using_chunked_transfer_encoding (a_string: READABLE_STRING_8; a_chunk_size: INTEGER; a_output: NETWORK_STREAM_SOCKET)
-- Append `a_file' content to `a_output'. local
i,n: INTEGER
do
from
i := 1
n := a_string.count
until
i > n
loop
put_chunk (a_string.substring (i, i + a_chunk_size), Void, a_output)
i := i + a_chunk_size
end
put_chunk_end (Void, Void, a_output)
end
put_chunk (a_content: READABLE_STRING_8; a_ext: detachable READABLE_STRING_8; a_output: NETWORK_STREAM_SOCKET)
-- Write chunk non empty `a_content' to `a_output'
-- with optional extension `a_ext': chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
-- Note: that header "Transfer-Encoding: chunked" is required.
require
a_content_not_empty: a_content /= Void and then not a_content.is_empty
valid_chunk_extension: (a_ext /= Void and then not a_ext.is_empty) implies
( a_ext.starts_with (";") and not a_ext.has ('%N') and not not a_ext.has ('%R') )
local
l_chunk_size_line: STRING_8
i: INTEGER
do
--| Remove all left '0'
l_chunk_size_line := a_content.count.to_hex_string
from
i := 1
until
l_chunk_size_line[i] /= '0'
loop
i := i + 1
end
if i > 1 then
l_chunk_size_line := l_chunk_size_line.substring (i, l_chunk_size_line.count)
end
if a_ext /= Void then
l_chunk_size_line.append (a_ext)
end
l_chunk_size_line.append (crlf)
a_output.put_string (l_chunk_size_line)
a_output.put_string (a_content)
a_output.put_string (crlf)
end
put_chunk_end (a_ext: detachable READABLE_STRING_8; a_trailer: detachable READABLE_STRING_8; a_output: NETWORK_STREAM_SOCKET)
-- Put end of chunked content,
-- with optional extension `a_ext': chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
-- and with optional trailer `a_trailer' : trailer= *(entity-header CRLF)
local
l_chunk_size_line: STRING_8
do
-- Chunk end
create l_chunk_size_line.make (1)
l_chunk_size_line.append_integer (0)
if a_ext /= Void then
l_chunk_size_line.append (a_ext)
end
l_chunk_size_line.append (crlf)
a_output.put_string (l_chunk_size_line)
-- Optional trailer
if a_trailer /= Void and then not a_trailer.is_empty then
a_output.put_string (a_trailer)
end
-- Final CRLF
a_output.put_string (crlf)
end
append_file_content_to_socket_using_chunked_transfer_encoding (a_file: FILE; a_len: INTEGER; a_chunk_size: INTEGER; a_output: NETWORK_STREAM_SOCKET)
-- Append `a_file' content as chunks of `a_chunk_size' length to `a_output'.
-- If `a_len' >= 0 then read only `a_len' characters. -- If `a_len' >= 0 then read only `a_len' characters.
require require
a_file_readable: a_file.exists and then a_file.is_access_readable a_file_readable: a_file.exists and then a_file.is_access_readable
@@ -523,7 +620,44 @@ feature {NONE} -- Helpers
until until
l_count = 0 or a_file.exhausted l_count = 0 or a_file.exhausted
loop loop
a_file.read_stream_thread_aware (l_count.min (2_048)) a_file.read_stream_thread_aware (l_count.min (a_chunk_size))
put_chunk (a_file.last_string, Void, a_output)
l_count := l_count - a_file.bytes_read
end
if not l_was_open then
a_file.close
end
put_chunk_end (Void, Void, a_output)
end
end
append_file_content_to_socket (a_file: FILE; a_len: INTEGER; a_output: NETWORK_STREAM_SOCKET)
-- Append `a_file' content to `a_output'.
-- If `a_len' >= 0 then read only `a_len' characters.
require
a_file_readable: a_file.exists and then a_file.is_access_readable
local
l_was_open: BOOLEAN
l_count, l_buffer_size: INTEGER
do
if a_len >= 0 then
l_count := a_len
else
l_count := a_file.count
end
if l_count > 0 then
l_was_open := a_file.is_open_read
if a_file.is_open_read then
l_was_open := True
else
a_file.open_read
end
from
l_buffer_size := buffer_size
until
l_count = 0 or a_file.exhausted
loop
a_file.read_stream_thread_aware (l_count.min (l_buffer_size))
a_output.put_string (a_file.last_string) a_output.put_string (a_file.last_string)
l_count := l_count - a_file.bytes_read l_count := l_count - a_file.bytes_read
end end
@@ -541,6 +675,7 @@ feature {NONE} -- Helpers
local local
l_was_open: BOOLEAN l_was_open: BOOLEAN
l_count: INTEGER l_count: INTEGER
l_buffer_size: INTEGER
do do
if a_len >= 0 then if a_len >= 0 then
l_count := a_len l_count := a_len
@@ -555,11 +690,11 @@ feature {NONE} -- Helpers
a_file.open_read a_file.open_read
end end
from from
l_buffer_size := buffer_size
until until
l_count = 0 or a_file.exhausted l_count = 0 or a_file.exhausted
loop loop
a_file.read_stream_thread_aware (l_count.min (2_048)) a_file.read_stream_thread_aware (l_count.min (l_buffer_size))
a_output.append (a_file.last_string) a_output.append (a_file.last_string)
l_count := l_count - a_file.bytes_read l_count := l_count - a_file.bytes_read
end end
@@ -632,7 +767,7 @@ feature {NONE} -- Helpers
-- FIXME: check solution! -- FIXME: check solution!
from from
l_count := 0 l_count := 0
l_chunk_size := 1_024 l_chunk_size := buffer_size
n := l_chunk_size --| value to satisfy until condition on first loop. n := l_chunk_size --| value to satisfy until condition on first loop.
until until
n < l_chunk_size or not a_socket.readable n < l_chunk_size or not a_socket.readable
@@ -718,16 +853,42 @@ feature {NONE} -- Helpers
end end
end end
new_mime_boundary: STRING new_mime_boundary (a_data: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_32]): STRING
-- New MIME boundary. -- New MIME boundary.
local
s: STRING
ran: RANDOM
n: INTEGER
i,j: INTEGER
do do
-- FIXME: better boundary creation across
Result := "----------------------------5eadfcf3bb3e" a_data as ic
loop
i := i + ic.item.count + ic.key.count
end
create ran.set_seed (i) -- FIXME: use a real random seed.
ran.start
ran.forth
n := (20 * ran.real_item).truncated_to_integer
create Result.make_filled ('-', 3 + n)
s := "_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
from
until
Result.count >= 40
loop
ran.forth
j := (ran.real_item * s.count).truncated_to_integer.max (1)
Result.append_character (s[j])
end
check Result.count = 40 and Result.starts_with ("---") end
end end
crlf: STRING = "%R%N"
-- CR and NL sequence.
invariant invariant
note 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)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -64,4 +64,9 @@ feature -- Tests
test_get_with_authentication test_get_with_authentication
end end
net_test_post_with_file_using_chunked_transfer_encoding
do
test_post_with_file_using_chunked_transfer_encoding
end
end end

View File

@@ -253,6 +253,38 @@ feature -- Factory
end end
end end
test_post_with_file_using_chunked_transfer_encoding
local
sess: HTTP_CLIENT_SESSION
h: STRING_8
l_ctx: HTTP_CLIENT_REQUEST_CONTEXT
do
if attached global_requestbin_path as requestbin_path then
-- POST REQUEST WITH A FILE AND FORM DATA
-- check requestbin to ensure the file and form parameters are correctly received
-- set filename to a local file
sess := new_session ("http://requestb.in")
create l_ctx.make
l_ctx.add_header ("Transfer-Encoding", "chunked")
l_ctx.set_upload_filename ("logo.jpg")
create h.make_empty
if
attached sess.post (requestbin_path, l_ctx, Void) as res and then
attached res.headers as hds
then
across
hds as c
loop
h.append (c.item.name + ": " + c.item.value + "%R%N")
end
end
print (h)
else
assert ("Has requestbin path", False)
end
end
test_get_with_redirection test_get_with_redirection
local local
sess: HTTP_CLIENT_SESSION sess: HTTP_CLIENT_SESSION

View File

@@ -8,7 +8,7 @@ class
inherit inherit
ANY ANY
SHARED_EXECUTION_ENVIRONMENT SHARED_EXECUTION_ENVIRONMENT
export export
{NONE} all {NONE} all
@@ -21,7 +21,7 @@ feature {NONE} -- Initialization
make_and_launch make_and_launch
local local
launcher: WSF_NINO_SERVICE_LAUNCHER [APPLICATION_EXECUTION] launcher: WSF_STANDALONE_SERVICE_LAUNCHER [APPLICATION_EXECUTION]
opts: WSF_SERVICE_LAUNCHER_OPTIONS opts: WSF_SERVICE_LAUNCHER_OPTIONS
do do
create opts.make create opts.make
@@ -32,24 +32,22 @@ feature {NONE} -- Initialization
launcher.launch launcher.launch
end end
on_launched (conn: WGI_CONNECTOR) on_launched (a_connector: WGI_STANDALONE_CONNECTOR [APPLICATION_EXECUTION])
local local
e: EXECUTION_ENVIRONMENT e: EXECUTION_ENVIRONMENT
cmd: STRING_32 cmd: STRING_32
do do
if attached {WGI_NINO_CONNECTOR [APPLICATION_EXECUTION]} conn as nino then e := execution_environment
e := execution_environment create cmd.make (32)
create cmd.make (32) if attached e.item ("COMSPEC") as l_comspec then
if attached e.item ("COMSPEC") as l_comspec then cmd.append (l_comspec)
cmd.append (l_comspec) cmd.append ({STRING_32} " /C start ")
cmd.append ({STRING_32} " /C start ")
end
cmd.append ("http://localhost:")
cmd.append_integer (nino.port)
cmd.append_character ({CHARACTER_32} '/')
e.launch (cmd)
end end
cmd.append ("http://localhost:")
cmd.append_integer (a_connector.port)
cmd.append_character ({CHARACTER_32} '/')
e.launch (cmd)
end end
end end

View File

@@ -42,12 +42,12 @@ feature {NONE} -- Initialization
m.set_title ("EWF::OpenID demo") m.set_title ("EWF::OpenID demo")
create s.make_empty create s.make_empty
s.append ("<form action=%"" + req.script_url ("/openid") + "%" method=%"POST%">%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='' 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 ("<input type='submit' name='op' value='sign with OpenID' />")
s.append ("</form>%N") s.append ("</form>%N")
s.append ("<form action=%"" + req.script_url ("/openid") + "%" method=%"POST%">%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 ("<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 Google' />") s.append ("<input type='submit' name='op' value='sign with Yahoo' />")
s.append ("</form>%N") s.append ("</form>%N")
m.set_body (s) m.set_body (s)
res.send (m) res.send (m)

View File

@@ -1,23 +1,26 @@
<?xml version="1.0" encoding="ISO-8859-1"?> <?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"> <target name="demo">
<root class="APPLICATION" feature="make_and_launch"/> <root class="APPLICATION" feature="make_and_launch"/>
<file_rule> <file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude> <exclude>/.svn$</exclude>
<exclude>/CVS$</exclude>
<exclude>/EIFGENs$</exclude>
</file_rule> </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"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </option>
<setting name="concurrency" value="thread"/> <setting name="concurrency" value="scoop"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <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" 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="http" location="..\..\..\..\network\protocol\http\http-safe.ecf"/>
<library name="openid" location="..\openid-safe.ecf" readonly="false"/> <library name="openid" location="..\openid-safe.ecf" readonly="false"/>
<library name="wsf" location="..\..\..\..\server\wsf\wsf-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"/> <cluster name="src" location=".\" recursive="true"/>
</target> </target>
<target name="demo_mt" extends="demo">
<setting name="concurrency" value="thread"/>
</target>
</system> </system>

View File

@@ -15,7 +15,7 @@
<library name="http_auth" location="..\http_authorization-safe.ecf"/> <library name="http_auth" location="..\http_authorization-safe.ecf"/>
<library name="encoders" location="..\..\..\..\text\encoder\encoder-safe.ecf"/> <library name="encoders" location="..\..\..\..\text\encoder\encoder-safe.ecf"/>
<library name="wsf" location="..\..\..\wsf\wsf-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"/> <cluster name="src" location=".\" recursive="true"/>
</target> </target>
</system> </system>

View File

@@ -2,7 +2,7 @@
## Overview ## Overview
The main goal of this library is to provide a common layer on top of many different connectors. 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. 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.

View File

@@ -10,6 +10,16 @@
<option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="all" syntax="standard"> <option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="all" syntax="standard">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </option>
<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="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="net" location="$ISE_LIBRARY\library\net\net-safe.ecf" readonly="false"/> <library name="net" location="$ISE_LIBRARY\library\net\net-safe.ecf" readonly="false"/>
<library name="net_ssl" location="$ISE_LIBRARY\unstable\library\network\socket\netssl\net_ssl-safe.ecf"> <library name="net_ssl" location="$ISE_LIBRARY\unstable\library\network\socket\netssl\net_ssl-safe.ecf">
@@ -18,21 +28,36 @@
</condition> </condition>
</library> </library>
<cluster name="network" location=".\network\"> <cluster name="network" location=".\network\">
<cluster name="ssl_network" location="$|ssl\" recursive="true"> <file_rule>
<condition> <exclude>/httpd_stream_socket_ext.e$</exclude>
<custom name="net_ssl_enabled" value="true"/>
</condition>
</cluster>
<cluster name="network_until_16_05" location="$|until_16_05\">
<condition> <condition>
<version type="compiler" max="16.11.0.0"/> <version type="compiler" max="16.11.0.0"/>
</condition> </condition>
</cluster> </file_rule>
<cluster name="network_from_16_11" location="$|from_16_11\"> <cluster name="ssl_network" location="$|ssl\" recursive="true">
<condition> <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> </condition>
</cluster> </cluster>
</cluster> </cluster>
</target> </target>
</system> </system>

View File

@@ -10,6 +10,16 @@
<option warning="true" full_class_checking="false" void_safety="none" syntax="standard"> <option warning="true" full_class_checking="false" void_safety="none" syntax="standard">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </option>
<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>
<setting name="concurrency" value="scoop"/> <setting name="concurrency" value="scoop"/>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="net" location="$ISE_LIBRARY\library\net\net.ecf"/> <library name="net" location="$ISE_LIBRARY\library\net\net.ecf"/>
@@ -19,19 +29,33 @@
</condition> </condition>
</library> </library>
<cluster name="network" location=".\network\"> <cluster name="network" location=".\network\">
<cluster name="ssl_network" location="$|ssl\" recursive="true"> <file_rule>
<condition> <exclude>/httpd_stream_socket_ext.e$</exclude>
<custom name="net_ssl_enabled" value="true"/>
</condition>
</cluster>
<cluster name="network_until_16_05" location="$|until_16_05\">
<condition> <condition>
<version type="compiler" max="16.11.0.0"/> <version type="compiler" max="16.11.0.0"/>
</condition> </condition>
</cluster> </file_rule>
<cluster name="network_from_16_11" location="$|from_16_11\"> <cluster name="ssl_network" location="$|ssl\" recursive="true">
<condition> <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> </condition>
</cluster> </cluster>
</cluster> </cluster>

View File

@@ -11,6 +11,16 @@
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </option>
<setting name="concurrency" value="scoop"/> <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="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="net" location="$ISE_LIBRARY\library\net\net-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"> <library name="net_ssl" location="$ISE_LIBRARY\unstable\library\network\socket\netssl\net_ssl-safe.ecf">
@@ -24,29 +34,12 @@
</condition> </condition>
</library> </library>
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/> <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"> <cluster name="httpd_server" location=".\" recursive="true">
<file_rule> <file_rule>
<exclude>/concurrency$</exclude> <exclude>/concurrency$</exclude>
<exclude>/network$</exclude>
<exclude>/no_ssl$</exclude> <exclude>/no_ssl$</exclude>
<exclude>/ssl$</exclude> <exclude>/ssl$</exclude>
<exclude>/network$</exclude>
</file_rule> </file_rule>
<cluster name="no_ssl" location="$|no_ssl\" recursive="true"> <cluster name="no_ssl" location="$|no_ssl\" recursive="true">
<condition> <condition>
@@ -74,5 +67,36 @@
</condition> </condition>
</cluster> </cluster>
</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> </target>
</system> </system>

View File

@@ -10,6 +10,16 @@
<option warning="true" full_class_checking="true" void_safety="none" syntax="standard"> <option warning="true" full_class_checking="true" void_safety="none" syntax="standard">
</option> </option>
<setting name="concurrency" value="thread"/> <setting name="concurrency" value="thread"/>
<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.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="net" location="$ISE_LIBRARY\library\net\net.ecf"/> <library name="net" location="$ISE_LIBRARY\library\net\net.ecf"/>
<library name="net_ssl" location="$ISE_LIBRARY\unstable\library\network\socket\netssl\net_ssl.ecf"> <library name="net_ssl" location="$ISE_LIBRARY\unstable\library\network\socket\netssl\net_ssl.ecf">
@@ -23,29 +33,12 @@
</condition> </condition>
</library> </library>
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/> <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\">
<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"> <cluster name="httpd_server" location=".\" recursive="true">
<file_rule> <file_rule>
<exclude>/concurrency$</exclude> <exclude>/concurrency$</exclude>
<exclude>/network$</exclude>
<exclude>/no_ssl$</exclude> <exclude>/no_ssl$</exclude>
<exclude>/ssl$</exclude> <exclude>/ssl$</exclude>
<exclude>/network$</exclude>
</file_rule> </file_rule>
<cluster name="no_ssl" location="$|no_ssl\" recursive="true"> <cluster name="no_ssl" location="$|no_ssl\" recursive="true">
<condition> <condition>
@@ -73,5 +66,36 @@
</condition> </condition>
</cluster> </cluster>
</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> </target>
</system> </system>

View File

@@ -31,7 +31,7 @@ feature {NONE} -- Initialization
reset reset
do do
reset_request reset_request (False)
reset_error reset_error
if attached internal_client_socket as l_sock then if attached internal_client_socket as l_sock then
@@ -40,10 +40,18 @@ feature {NONE} -- Initialization
internal_client_socket := Void internal_client_socket := Void
end end
reset_request reset_request (a_is_reusing_connection: BOOLEAN)
-- Reset the request, and `a_is_reusing_connection' says if the peristent connection is
-- still alive.
do do
if a_is_reusing_connection then
-- Keep `remote_info' as it stays the same for the successive
-- persistent connections.
else
remote_info := Void
end
version := Void version := Void
remote_info := Void
-- FIXME: optimize to just wipe_out if needed -- FIXME: optimize to just wipe_out if needed
create method.make_empty create method.make_empty
@@ -154,7 +162,7 @@ feature -- Settings
feature -- Status report feature -- Status report
has_error: BOOLEAN has_error: BOOLEAN
-- Error occurred during `analyze_request_message' -- Error occurred during `get_request_header'
feature -- Status change feature -- Status change
@@ -208,11 +216,21 @@ feature -- Execution
is_connected: is_connected is_connected: is_connected
local local
l_socket: like client_socket l_socket: like client_socket
l_remote_info: detachable like remote_info
l_exit: BOOLEAN l_exit: BOOLEAN
n,m: INTEGER n,m: INTEGER
do do
l_socket := client_socket 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 check
socket_attached: l_socket /= Void socket_attached: l_socket /= Void
socket_valid: l_socket.is_open_read and then l_socket.is_open_write socket_valid: l_socket.is_open_read and then l_socket.is_open_write
@@ -237,7 +255,7 @@ feature -- Execution
or not is_next_persistent_connection_supported -- related to `max_keep_alive_requests' or not is_next_persistent_connection_supported -- related to `max_keep_alive_requests'
or not is_persistent_connection_requested or not is_persistent_connection_requested
or has_error or l_socket.is_closed or not l_socket.is_open_read or has_error or l_socket.is_closed or not l_socket.is_open_read
reset_request reset_request (not l_exit)
end end
if l_exit and has_error and not l_socket.is_closed then if l_exit and has_error and not l_socket.is_closed then
l_socket.close l_socket.close
@@ -251,10 +269,9 @@ feature -- Execution
is_connected: is_connected is_connected: is_connected
reuse_connection_when_possible: a_is_reusing_connection implies is_persistent_connection_supported reuse_connection_when_possible: a_is_reusing_connection implies is_persistent_connection_supported
no_error: not has_error no_error: not has_error
remote_info_set: remote_info /= Void
local local
l_remote_info: detachable like remote_info
l_socket: like client_socket l_socket: like client_socket
l_is_ready: BOOLEAN
do do
debug ("dbglog") debug ("dbglog")
if a_is_reusing_connection then if a_is_reusing_connection then
@@ -276,50 +293,34 @@ feature -- Execution
dbglog ("execute_request socket=" + l_socket.descriptor.out + " ENTER") dbglog ("execute_request socket=" + l_socket.descriptor.out + " ENTER")
end end
if a_is_reusing_connection then -- Try to get request header.
--| set by default 5 seconds. -- If the request is reusing persistent connection, use `keep_alive_timeout',
l_socket.set_recv_timeout (keep_alive_timeout) -- in seconds! -- otherwise `socket_recv_timeout'.
l_is_ready := socket_has_incoming_data (l_socket) get_request_header (l_socket, a_is_reusing_connection)
else
l_is_ready := True
end
if l_is_ready then if has_error then
l_socket.set_recv_timeout (socket_recv_timeout) -- FIXME: return a 408 Request Timeout response .. if a_is_reusing_connection and then request_header.is_empty then
create l_remote_info -- Close persistent connection, since no new connection occurred in the delay `keep_alive_timeout'.
if attached l_socket.peer_address as l_addr then debug ("dbglog")
l_remote_info.addr := l_addr.host_address.host_address dbglog ("execute_request socket=" + l_socket.descriptor.out + "} close persistent connection.")
l_remote_info.hostname := l_addr.host_address.host_name end
l_remote_info.port := l_addr.port else
remote_info := l_remote_info
end
analyze_request_message (l_socket)
if has_error then
-- check catch_bad_incoming_connection: False end
if is_verbose then if is_verbose then
log (request_header + "%NWARNING: invalid HTTP incoming request", warning_level) log (request_header + "%NWARNING: invalid HTTP incoming request", warning_level)
end end
process_bad_request (l_socket) process_bad_request (l_socket)
is_persistent_connection_requested := False end
else is_persistent_connection_requested := False
if is_verbose then else
log (request_header, information_level) if is_verbose then
end log (request_header, information_level)
process_request (l_socket) end
end process_request (l_socket)
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 end
debug ("dbglog") debug ("dbglog")
dbglog ("execute_request {" + l_socket.descriptor.out + "} LEAVE") dbglog ("execute_request {" + l_socket.descriptor.out + "} LEAVE")
end end
end end
end end
@@ -377,8 +378,11 @@ feature -- Request processing
feature -- Parsing feature -- Parsing
analyze_request_message (a_socket: HTTPD_STREAM_SOCKET) get_request_header (a_socket: HTTPD_STREAM_SOCKET; a_is_reusing_connection: BOOLEAN)
-- Analyze message extracted from `a_socket' as HTTP request -- 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 require
input_readable: a_socket /= Void and then a_socket.is_open_read input_readable: a_socket /= Void and then a_socket.is_open_read
local local
@@ -391,76 +395,90 @@ feature -- Parsing
do do
create txt.make (64) create txt.make (64)
request_header := txt request_header := txt
l_is_verbose := is_verbose
if if
not has_error and then not has_error and then
a_socket.readable a_socket.readable
then 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 if
attached next_line (a_socket) as l_request_line and then 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 then
txt.append (l_request_line) txt.append (l_request_line)
txt.append_character ('%N') txt.append_character ('%N')
analyze_request_line (l_request_line) 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 else
report_error ("Bad header line (empty)") report_error ("Bad header line (empty)")
end end
else else
report_error ("Socket is not readable") report_error ("Socket is not readable")
end 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 end
analyze_request_line (line: STRING) 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 require
valid_line: line /= Void and then not line.is_empty valid_line: line /= Void and then not line.is_empty
local local
@@ -488,28 +506,26 @@ feature -- Parsing
next_line (a_socket: HTTPD_STREAM_SOCKET): detachable STRING next_line (a_socket: HTTPD_STREAM_SOCKET): detachable STRING
-- Next line fetched from `a_socket' is available. -- Next line fetched from `a_socket' is available.
-- note: may update `has_error'.
require require
not_has_error: not has_error or is_verbose not_has_error: not has_error
is_readable: a_socket.is_open_read is_readable: a_socket.is_open_read
local local
retried: BOOLEAN retried: BOOLEAN
do do
if retried then if retried then
report_error ("Rescue in next_line") report_error ("Rescue in next_line")
a_socket.close
Result := Void Result := Void
elseif elseif a_socket.readable then
a_socket.readable and then a_socket.read_line_noexception
socket_has_incoming_data (a_socket)
then
a_socket.read_line_thread_aware
Result := a_socket.last_string 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. -- 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") report_error ("Socket error")
if is_verbose then 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
end end
else else
@@ -520,6 +536,7 @@ feature -- Parsing
end end
end end
rescue rescue
-- In case of network error exception (as EiffelNet reports error raising exception)
retried := True retried := True
retry retry
end end
@@ -558,7 +575,9 @@ feature {NONE} -- Helpers
a_socket.readable a_socket.readable
do do
-- FIXME: check if both are really needed. -- 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 end
invariant invariant

View File

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

View File

@@ -1,369 +1,235 @@
note note
description: "[ description: "Summary description for {HTTPD_STREAM_SOCKET}."
Summary description for {HTTPD_STREAM_SOCKET}
that can be used for http or https connection.
]"
date: "$Date$" date: "$Date$"
revision: "$Revision$" revision: "$Revision$"
class class
HTTPD_STREAM_SOCKET HTTPD_STREAM_SOCKET
inherit
NETWORK_STREAM_SOCKET
HTTPD_STREAM_SOCKET_EXT
create create
make_server_by_address_and_port, make, make_empty,
make_server_by_port, make_client_by_port, make_client_by_address_and_port,
make_client_by_address_and_port, make_server_by_port, make_server_by_address_and_port, make_loopback_server_by_port
make_client_by_port,
make_from_separate,
make_empty
create {HTTPD_STREAM_SOCKET} create {NETWORK_STREAM_SOCKET}
make 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 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 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 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 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 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 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 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 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 require
descriptor_available: s.descriptor_available readable: readable
socket_exists: exists
local
ext: C_STRING
retval: INTEGER
l: like last_string
do do
create {TCP_STREAM_SOCKET} socket.make_from_separate (s.socket) create ext.make_empty (nb_char + 1)
end retval := c_recv_noexception (descriptor, ext.item, nb_char, c_peekmsg)
if retval = 0 then
make_empty last_string.wipe_out
do socket_error := Void
create {TCP_STREAM_SOCKET} socket.make_empty elseif retval > 0 then
end ext.set_count (retval)
l := last_string
retrieve_socket (s: HTTPD_STREAM_SOCKET): INTEGER l.wipe_out
do l.grow (retval)
Result := s.socket.descriptor l.set_count (retval)
end ext.read_substring_into (l, 1, retval)
socket_error := Void
feature -- Change else
last_string.wipe_out
set_timeout (n: INTEGER) socket_error := "Socket error (MSG_PEEK)"
-- Set timeout to `n' seconds.
do
if attached {NETWORK_STREAM_SOCKET} socket as l_socket then
l_socket.set_timeout (n)
end end
ensure
last_string_not_void: last_string /= Void
end end
set_connect_timeout (n: INTEGER) feature {NONE} -- Input
do
if attached {NETWORK_STREAM_SOCKET} socket as l_socket then
l_socket.set_connect_timeout (n)
end
end
set_accept_timeout (n: INTEGER) read_into_pointer_noexception (p: POINTER; start_pos, nb_bytes: INTEGER_32)
do -- Read at most `nb_bytes' bound bytes and make result
if attached {NETWORK_STREAM_SOCKET} socket as l_socket then -- available in `p' at position `start_pos'.
l_socket.set_accept_timeout (n) -- No exception raised!
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)
require 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 do
if attached {TCP_STREAM_SOCKET} socket as l_socket then from
l_socket.peek_stream (nb_char) 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
end bytes_read := l_read
ensure
bytes_read: INTEGER bytes_read_updated: 0 <= bytes_read and bytes_read <= nb_bytes
do
Result := socket.bytes_read
end end
feature -- Output 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 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 end
put_readable_string_8 (s: READABLE_STRING_8) put_readable_string_8 (s: READABLE_STRING_8)
-- Write readable string `s' to socket. -- Write readable string `s' to socket.
local
ext: C_STRING
do do
if attached {TCP_STREAM_SOCKET} socket as l_tcp_stream_socket then create ext.make (s)
l_tcp_stream_socket.put_readable_string_8 (s) put_managed_pointer (ext.managed_data, 0, s.count)
else
put_string (s)
end
end end
put_string (s: STRING) feature -- Status report
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
has_incoming_data: BOOLEAN has_incoming_data: BOOLEAN
-- Check if Current has available data to be read. -- Check if Current has available data to be read.
-- note: no data will not be removed from the queue. -- note: no data will not be removed from the queue.
require
socket_exists: exists
do do
if attached {TCP_STREAM_SOCKET} socket as l_socket then peek_stream_noexception (1)
Result := l_socket.has_incoming_data Result := last_string.count = 1
end
end end
ready_for_reading: BOOLEAN note
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
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
@@ -373,4 +239,5 @@ feature {HTTPD_STREAM_SOCKET} -- Implementation
Website http://www.eiffel.com Website http://www.eiffel.com
Customer support http://support.eiffel.com Customer support http://support.eiffel.com
]" ]"
end end

View File

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

View File

@@ -1,8 +1,5 @@
note note
description: "[ description: "SSL tcp stream socket."
Summary description for {HTTPD_STREAM_SSL_SOCKET}
that can be used for http or https connection.
]"
date: "$Date$" date: "$Date$"
revision: "$Revision$" revision: "$Revision$"
@@ -11,159 +8,142 @@ class
inherit inherit
HTTPD_STREAM_SOCKET 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 redefine
port, put_managed_pointer,
is_bound, read_stream_noexception,
ready_for_writing, read_into_pointer_noexception,
ready_for_reading, put_pointer_content_noexception
try_ready_for_reading,
put_readable_string_8,
make_empty
end 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 create
make_ssl_server_by_address_and_port, make_ssl_server_by_port, make, make_empty,
make_server_by_address_and_port, make_server_by_port, make_client_by_port, make_client_by_address_and_port,
make_ssl_client_by_address_and_port, make_ssl_client_by_port, make_server_by_port, make_server_by_address_and_port, make_loopback_server_by_port
make_client_by_address_and_port, make_client_by_port,
make_empty
create {HTTPD_STREAM_SOCKET} create {SSL_NETWORK_STREAM_SOCKET}
make 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 local
l_socket: SSL_TCP_STREAM_SOCKET ext: C_STRING
return_val: INTEGER
do do
create l_socket.make_server_by_address_and_port (an_address, a_port) if
l_socket.set_tls_protocol (a_ssl_protocol) attached context as l_context and then
socket := l_socket attached l_context.last_ssl as l_ssl
set_certificates (a_crt_fn, a_key_fn) 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 end
make_ssl_server_by_port (a_port: INTEGER; a_ssl_protocol: NATURAL; a_crt_fn, a_key_fn: detachable READABLE_STRING_GENERAL) feature {NONE} -- Input
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
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 local
l_socket: SSL_TCP_STREAM_SOCKET l_read: INTEGER
l_last_read: INTEGER
do do
create l_socket.make_client_by_address_and_port (an_address, a_port) if
l_socket.set_tls_protocol (a_ssl_protocol) attached context as l_context and then
socket := l_socket attached l_context.last_ssl as l_ssl
set_certificates (a_crt_fn, a_key_fn) then
end from
l_last_read := 1
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) until
local l_read = nb_bytes or l_last_read <= 0
l_socket: SSL_TCP_STREAM_SOCKET loop
do l_last_read := l_ssl.read (p + start_pos + l_read, nb_bytes - l_read)
create l_socket.make_client_by_port (a_peer_port, a_peer_host) if l_last_read >= 0 then
l_socket.set_tls_protocol (a_ssl_protocol) l_read := l_read + l_last_read
socket := l_socket end
set_certificates (a_crt_fn, a_key_fn) end
end bytes_read := l_read
else
make_empty check has_context: False end
-- <Precursor>. end
do
create {SSL_TCP_STREAM_SOCKET} socket.make_empty
end end
feature -- Output feature -- Output
put_readable_string_8 (s: READABLE_STRING_8) put_managed_pointer (p: MANAGED_POINTER; start_pos, nb_bytes: INTEGER)
-- <Precursor> -- Put data of length `nb_bytes' pointed by `start_pos' index in `p' at
-- current position.
do do
if attached {SSL_TCP_STREAM_SOCKET} socket as l_ssl_socket then Precursor {HTTPD_STREAM_SOCKET} (p, start_pos, nb_bytes)
l_ssl_socket.put_readable_string_8 (s)
else
Precursor (s)
end
end end
feature -- Status Report put_pointer_content_noexception (a_pointer: POINTER; a_offset, a_byte_count: INTEGER)
-- Write `a_byte_count' bytes to the socket.
port: INTEGER -- The data is taken from the memory area pointed to by `a_pointer', at offset `a_offset'.
-- <Precursor> -- Update `bytes_sent'.
-- No exception raised!
local
l_bytes_sent: INTEGER
do do
if attached {SSL_TCP_STREAM_SOCKET} socket as l_ssl_socket then if
Result := l_ssl_socket.port attached context as l_context and then
else attached l_context.last_ssl as l_ssl
Result := Precursor then
end l_bytes_sent := ssl_write (l_ssl, a_pointer + a_offset, a_byte_count)
end if l_bytes_sent < a_byte_count then
socket_error := "No all bytes sent!"
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)
end 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
end end
note 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)" 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 end

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -20,13 +20,19 @@ create
feature {NONE} -- Factory feature {NONE} -- Factory
new_listening_socket (a_addr: detachable INET_ADDRESS; a_http_port: INTEGER): HTTPD_STREAM_SOCKET new_listening_socket (a_addr: detachable INET_ADDRESS; a_http_port: INTEGER): HTTPD_STREAM_SOCKET
local
s_ssl: HTTPD_STREAM_SSL_SOCKET
do do
if configuration.is_secure then if configuration.is_secure then
if a_addr /= Void 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 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 end
s_ssl.set_tls_protocol (configuration.ssl_protocol)
s_ssl.set_certificate_filenames (configuration.ca_crt, configuration.ca_key)
Result := s_ssl
else else
Result := Precursor (a_addr, a_http_port) Result := Precursor (a_addr, a_http_port)
end end

View File

@@ -35,10 +35,10 @@ feature {NONE} -- Initialization
initialize_server (server) initialize_server (server)
end 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' -- Create current standalone connector with base url `a_base'
require 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 do
make make
set_base (a_base) set_base (a_base)
@@ -109,7 +109,8 @@ feature -- Status report
feature -- Callbacks feature -- Callbacks
on_launched_actions: ACTION_SEQUENCE [TUPLE [WGI_STANDALONE_CONNECTOR [WGI_EXECUTION]]] 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 feature -- Event
@@ -123,16 +124,25 @@ feature -- Event
feature -- Element change feature -- Element change
set_base (v: like base) set_base (v: detachable separate READABLE_STRING_8)
-- Set base url `base' to `v'. -- Set base url `base' to `v'.
require 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 do
base := v if v = Void then
base := Void
else
create {STRING_8} base.make_from_separate (v)
end
ensure ensure
valid_base: (attached base as l_base and then not l_base.is_empty) implies l_base.starts_with ("/") valid_base: (attached base as l_base and then not l_base.is_empty) implies l_base.starts_with ("/")
end 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 (a_port_number: INTEGER)
-- Set port number to `a_port_number'. -- Set port number to `a_port_number'.
require require
@@ -141,6 +151,13 @@ feature -- Element change
set_port_on_configuration (a_port_number, configuration) set_port_on_configuration (a_port_number, configuration)
end 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_max_concurrent_connections (nb: INTEGER)
-- Set maximum concurrent connections to `nb'. -- Set maximum concurrent connections to `nb'.
require require
@@ -164,6 +181,13 @@ feature -- Element change
feature -- Server 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
-- Launch web server listening. -- Launch web server listening.
do do
@@ -189,12 +213,12 @@ feature -- Events
require require
obs.started -- SCOOP wait condition. obs.started -- SCOOP wait condition.
do do
-- FIXME: this works only with SCOOP concurrency mode. [2016-oct-07]
if obs.port > 0 then if obs.port > 0 then
on_launched (obs.port) on_launched (obs.port)
end end
end end
feature {NONE} -- Implementation feature {NONE} -- Implementation
server_controller (a_server: like server): separate HTTPD_CONTROLLER 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) cfg.set_http_server_port (a_port_number)
end 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) set_max_concurrent_connections_on_configuration (nb: INTEGER; cfg: like configuration)
do do
cfg.set_max_concurrent_connections (nb) cfg.set_max_concurrent_connections (nb)

View File

@@ -42,8 +42,8 @@ feature -- Input
src: like source src: like source
do do
src := source src := source
if src.readable then if src.readable and not src.was_error then
src.read_character src.read_character_noexception
last_character := src.last_character last_character := src.last_character
else else
last_character := '%U' last_character := '%U'
@@ -56,8 +56,8 @@ feature -- Input
do do
src := source src := source
last_string.wipe_out last_string.wipe_out
if src.readable then if src.readable and not src.was_error then
src.read_stream_thread_aware (nb) src.read_stream_noexception (nb)
last_string.append_string (src.last_string) last_string.append_string (src.last_string)
end end
end end
@@ -85,11 +85,11 @@ feature -- Status report
end_of_input: BOOLEAN end_of_input: BOOLEAN
-- Has the end of input stream been reached? -- Has the end of input stream been reached?
do do
Result := not source.readable Result := not source.readable or source.was_error
end end
;note ;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)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -75,23 +75,23 @@ feature -- Output
-- Send `s' to http client -- Send `s' to http client
do do
last_target_call_succeed := False last_target_call_succeed := False
target.put_readable_string_8 (s) target.put_readable_string_8_noexception (s)
last_target_call_succeed := True last_target_call_succeed := not target.was_error
end end
put_string (s: READABLE_STRING_8) put_string (s: READABLE_STRING_8)
-- Send `s' to http client -- Send `s' to http client
do do
last_target_call_succeed := False last_target_call_succeed := False
target.put_readable_string_8 (s) target.put_readable_string_8_noexception (s)
last_target_call_succeed := True last_target_call_succeed := not target.was_error
end end
put_character (c: CHARACTER_8) put_character (c: CHARACTER_8)
do do
last_target_call_succeed := False last_target_call_succeed := False
target.put_character (c) target.put_character_noexception (c)
last_target_call_succeed := True last_target_call_succeed := not target.was_error
end end
feature -- Status report feature -- Status report
@@ -116,7 +116,7 @@ feature -- Basic operations
end end
note 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)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -11,7 +11,7 @@
</option> </option>
<setting name="concurrency" value="thread"/> <setting name="concurrency" value="thread"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <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"/> <library name="ewsgi" location="..\..\ewsgi-safe.ecf" readonly="false"/>
<cluster name="src" location="src\" recursive="true"/> <cluster name="src" location="src\" recursive="true"/>
</target> </target>

View File

@@ -11,7 +11,7 @@
</option> </option>
<setting name="concurrency" value="thread"/> <setting name="concurrency" value="thread"/>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/> <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"/> <library name="ewsgi" location="..\..\ewsgi.ecf" readonly="false"/>
<cluster name="src" location="src\" recursive="true"/> <cluster name="src" location="src\" recursive="true"/>
</target> </target>

View File

@@ -14,14 +14,14 @@ feature {NONE} -- Initialization
make make
do 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") 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 {NINO_SERVICE [HELLO_WORLD_EXECUTION]}.make_custom ("")).listen (port_number) (create {WGI_STANDALONE_CONNECTOR [HELLO_WORLD_EXECUTION]}.make_with_base ("")).launch_on_port (port_number)
end end
port_number: INTEGER = 8123 port_number: INTEGER = 8123
note 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)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -18,12 +18,12 @@ feature {NONE} -- Initialization
execute execute
do do
response.set_status_code (200, Void) 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") response.put_string ("Hello World!%N")
end end
note 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)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -35,6 +35,9 @@ feature -- Input
read_character read_character
-- Read the next character in input stream. -- Read the next character in input stream.
-- Make the result available in `last_character' -- Make the result available in `last_character'
local
d: like last_chunk_data
l_index_in_chunk: INTEGER
do do
index := index + 1 index := index + 1
if index > chunk_upper then if index > chunk_upper then
@@ -45,10 +48,24 @@ feature -- Input
read_trailer_and_crlf read_trailer_and_crlf
last_character := '%U' last_character := '%U'
else else
last_character := last_chunk_data.item (index) l_index_in_chunk := chunk_index (index)
d := last_chunk_data
if d.valid_index (l_index_in_chunk) then
last_character := d [l_index_in_chunk]
else
check has_character: False end
last_character := '%U'
end
end end
else else
last_character := last_chunk_data.item (index) l_index_in_chunk := chunk_index (index)
d := last_chunk_data
if d.valid_index (l_index_in_chunk) then
last_character := d [l_index_in_chunk]
else
check has_character: False end
last_character := '%U'
end
end end
end end
@@ -77,13 +94,13 @@ feature -- Input
i - index + 1 = nb or last_chunk_size = 0 i - index + 1 = nb or last_chunk_size = 0
loop loop
if i + nb - 1 <= chunk_upper then if i + nb - 1 <= chunk_upper then
last_string.append (last_chunk_data.substring (i - chunk_lower + 1, i - chunk_lower + 1 + nb - 1)) last_string.append (last_chunk_data.substring (chunk_index (i), chunk_index (i) + nb - 1))
i := i + nb - 1 i := i + nb - 1
else else
-- Need to read new chunk -- Need to read new chunk
-- first get all available data from current chunk -- first get all available data from current chunk
if i <= chunk_upper then if i > chunk_upper then
last_string.append (last_chunk_data.substring (i - chunk_lower + 1, chunk_upper - chunk_lower + 1)) last_string.append (last_chunk_data.substring (i - chunk_lower + 1, chunk_index (chunk_upper)))
i := chunk_upper i := chunk_upper
end end
-- then continue -- then continue
@@ -166,9 +183,25 @@ feature -- Status report
Result := last_trailer /= Void Result := last_trailer /= Void
end end
feature {NONE} -- Parser feature {NONE} -- Access: chunk
chunk_index (a_index: INTEGER): INTEGER
-- Index in `last_chunk_data' for global input index `a_index'.
do
Result := a_index - chunk_lower + 1
end
index: INTEGER
-- Global input index.
chunk_lower: INTEGER
-- Lower global index for `last_chunk_data'.
chunk_upper: INTEGER
-- Upper global index for `last_chunk_data'.
feature {NONE} -- Chunk parsing
index, chunk_lower, chunk_upper: INTEGER
tmp_hex_chunk_size: STRING_8 tmp_hex_chunk_size: STRING_8
read_chunk_block read_chunk_block
@@ -190,8 +223,10 @@ feature {NONE} -- Parser
check last_chunk_data.count = last_chunk_size end check last_chunk_data.count = last_chunk_size end
l_input := input l_input := input
check not l_input.end_of_input end
l_input.read_character l_input.read_character
check l_input.last_character = '%R' end check l_input.last_character = '%R' end
check not l_input.end_of_input end
l_input.read_character l_input.read_character
check l_input.last_character = '%N' end check l_input.last_character = '%N' end
end end
@@ -214,8 +249,8 @@ feature {NONE} -- Parser
l_input.read_string (last_chunk_size) l_input.read_string (last_chunk_size)
last_chunk_data := l_input.last_string last_chunk_data := l_input.last_string
ensure ensure
last_chunk_attached: attached last_chunk_data as el_last_chunk last_chunk_attached: last_chunk_data /= Void
last_chunk_size_ok: el_last_chunk.count = last_chunk_size last_chunk_size_ok: last_chunk_data.count = last_chunk_size
end end
read_chunk_size read_chunk_size
@@ -350,7 +385,7 @@ feature {NONE} -- Implementation
-- Input Stream -- Input Stream
;note ;note
copyright: "2011-2013, 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)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -12,11 +12,12 @@
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <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_cgi" location="..\..\ewsgi\connectors\cgi\cgi-safe.ecf"/>
<library name="connector_libfcgi" location="..\..\ewsgi\connectors\libfcgi\libfcgi-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="encoder" location="..\..\..\text\encoder\encoder-safe.ecf" readonly="false"/>
<library name="error" location="..\..\..\utility\general\error\error-safe.ecf"/> <library name="error" location="..\..\..\utility\general\error\error-safe.ecf"/>
<library name="ewsgi" location="..\..\ewsgi\ewsgi-safe.ecf"/> <library name="ewsgi" location="..\..\ewsgi\ewsgi-safe.ecf"/>
<library name="http" location="..\..\..\network\protocol\http\http-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"> <library name="nino" location="nino-safe.ecf" readonly="false">
<renaming old_name="HTTP_CONSTANTS" new_name="NINO_HTTP_CONSTANTS"/> <renaming old_name="HTTP_CONSTANTS" new_name="NINO_HTTP_CONSTANTS"/>
</library> </library>
@@ -24,6 +25,6 @@
<library name="wsf" location="..\wsf-safe.ecf"/> <library name="wsf" location="..\wsf-safe.ecf"/>
<cluster name="wsf_cgi" location=".\cgi\" recursive="true"/> <cluster name="wsf_cgi" location=".\cgi\" recursive="true"/>
<cluster name="wsf_libfcgi" location=".\libfcgi\" 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> </target>
</system> </system>

View File

@@ -12,7 +12,7 @@
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="ewsgi" location="..\..\ewsgi\ewsgi-safe.ecf"/> <library name="ewsgi" location="..\..\ewsgi\ewsgi-safe.ecf"/>
<library name="wsf" location="..\wsf-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"/> <cluster name="wsf_openshift" location=".\openshift\" recursive="true"/>
</target> </target>
</system> </system>

View File

@@ -2,13 +2,12 @@ note
description: "[ description: "[
Component to launch the service using the default connector 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: This default connector support options:
base: base_url (very specific to standalone server) base: base_url (very specific to standalone server)
verbose: to display verbose output, useful for Nino verbose: to display verbose output, useful for standalone
force_single_threaded: use only one thread, useful for Nino
check WSF_SERVICE_LAUNCHER for more documentation check WSF_SERVICE_LAUNCHER for more documentation
]" ]"
@@ -19,7 +18,7 @@ class
WSF_OPENSHIFT_SERVICE_LAUNCHER [G -> WSF_EXECUTION create make end] WSF_OPENSHIFT_SERVICE_LAUNCHER [G -> WSF_EXECUTION create make end]
inherit inherit
WSF_NINO_SERVICE_LAUNCHER [G] WSF_STANDALONE_SERVICE_LAUNCHER [G]
redefine redefine
initialize initialize
end end

View File

@@ -64,7 +64,7 @@ feature {NONE} -- Initialization
verbose := False verbose := False
verbose_level := notice_level verbose_level := notice_level
base_url := "" base_url := Void
if attached options as opts then if attached options as opts then
if attached {READABLE_STRING_GENERAL} opts.option ("server_name") as l_server_name then if attached {READABLE_STRING_GENERAL} opts.option ("server_name") as l_server_name then
@@ -175,7 +175,12 @@ feature -- Execution
else else
io.error.put_string ("localhost") io.error.put_string ("localhost")
end 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
end end
update_configuration (conn.configuration) update_configuration (conn.configuration)
@@ -201,7 +206,7 @@ feature {NONE} -- Implementation
server_name: detachable READABLE_STRING_8 server_name: detachable READABLE_STRING_8
base_url: READABLE_STRING_8 base_url: detachable READABLE_STRING_8
verbose: BOOLEAN verbose: BOOLEAN
verbose_level: INTEGER verbose_level: INTEGER

View File

@@ -2,11 +2,10 @@ note
description: "[ description: "[
Options used by WSF_SERVICE_LAUNCHER 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") port: numeric such as 8099 (or equivalent string as "8099")
base: base_url (very specific to standalone server) 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 Standalone
verbose: to display verbose output, useful for Nino
]" ]"
date: "$Date: 2016-08-06 13:34:52 +0200 (sam., 06 août 2016) $" date: "$Date: 2016-08-06 13:34:52 +0200 (sam., 06 août 2016) $"
revision: "$Revision: 99106 $" revision: "$Revision: 99106 $"

View File

@@ -288,7 +288,7 @@ feature -- Access: Input
end end
end end
if raw_input_data_recorded then if raw_input_data_recorded then
set_raw_input_data (buf.substring (buf_initial_size + 1, buf.count)) set_raw_input_data (buf.substring (buf_initial_size + 1, buf.count))
-- Only the input data! And differente reference. -- Only the input data! And differente reference.
end end
end end
@@ -833,6 +833,7 @@ feature -- Access: CGI meta parameters - 1.1
local local
l_result: like internal_percent_encoded_path_info l_result: like internal_percent_encoded_path_info
r: READABLE_STRING_8 r: READABLE_STRING_8
pi: READABLE_STRING_32
i,m,n,spos: INTEGER i,m,n,spos: INTEGER
do do
l_result := internal_percent_encoded_path_info l_result := internal_percent_encoded_path_info
@@ -844,11 +845,23 @@ feature -- Access: CGI meta parameters - 1.1
else else
l_result := r.string l_result := r.string
end end
if attached script_name as s then pi := path_info
i := 0
if pi.is_valid_as_string_8 then
i := l_result.substring_index (pi.to_string_8, 1)
if i > 0 then
-- Path info is included in REQUEST_URI
-- so let's get the percent encoded path info from request uri.
l_result := l_result.substring (i, l_result.count)
end
end
--| here "i = 0" means request_uri does not start with `path_info',
--| thus let's compute it from `script_name'.
if i = 0 and attached script_name as s then
if l_result.starts_with (s) then if l_result.starts_with (s) then
l_result := l_result.substring (s.count + 1, l_result.count) l_result := l_result.substring (s.count + 1, l_result.count)
else else
--| Handle Rewrite url engine, to have clean path --| Handle Rewrite url engine, to have clean path
from from
i := 1 i := 1
m := l_result.count m := l_result.count
@@ -2083,7 +2096,7 @@ invariant
wgi_request.content_type /= Void implies content_type /= Void wgi_request.content_type /= Void implies content_type /= Void
note note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others" copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -11,9 +11,9 @@
</option> </option>
<setting name="concurrency" value="thread"/> <setting name="concurrency" value="thread"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <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="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="ewsgi" location="..\..\..\ewsgi\ewsgi-safe.ecf" readonly="false"/>
<library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/> <library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
<library name="wsf" location="..\..\wsf-safe.ecf" readonly="false"/> <library name="wsf" location="..\..\wsf-safe.ecf" readonly="false"/>

View File

@@ -13,11 +13,17 @@ feature {NONE} -- Initialization
make make
-- Initialize `Current'. -- Initialize `Current'.
local
base_url: detachable READABLE_STRING_8
do do
print ("Test Server that could be used for autotest%N") 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) set_service_option ("verbose", True)
make_and_launch make_and_launch
end end

View File

@@ -35,6 +35,13 @@ feature -- Helper
end end
base_url: detachable STRING 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 test_url (a_query_url: READABLE_STRING_8): READABLE_STRING_8
local local
@@ -44,7 +51,7 @@ feature -- Helper
if b = Void then if b = Void then
b := "" b := ""
end end
Result := "/" + b + a_query_url Result := b + a_query_url
end end
end end

View 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

View File

@@ -19,33 +19,49 @@ inherit
feature {NONE} -- Events feature {NONE} -- Events
web_app: detachable NINO_SERVICE [TEST_EXECUTION] web_connector: detachable separate WGI_STANDALONE_CONNECTOR [TEST_EXECUTION]
port_number: INTEGER 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 on_prepare
-- <Precursor> -- <Precursor>
local local
app: NINO_SERVICE [TEST_EXECUTION] conn: separate WGI_STANDALONE_CONNECTOR [TEST_EXECUTION]
wt: WORKER_THREAD
e: EXECUTION_ENVIRONMENT e: EXECUTION_ENVIRONMENT
do do
create e 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 if port_number = 0 then
server_log ("== Current directory: " + e.current_working_directory) 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)) if attached base_url as b then
wt.launch create conn.make_with_base (b)
e.sleep (1_000_000_000 * 5) else
port_number := app.port create conn.make
server_log ("Server port=" + port_number.out) 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 else
server_log ("Use existing server") server_log ("Use existing server")
server_log ("== Current directory: " + e.current_working_directory) server_log ("== Current directory: " + e.current_working_directory)
@@ -53,6 +69,26 @@ feature {NONE} -- Events
end end
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 server_log_name: STRING
local local
fn: FILE_NAME fn: FILE_NAME
@@ -78,9 +114,9 @@ feature {NONE} -- Events
test_url (a_query_url: READABLE_STRING_8): READABLE_STRING_8 test_url (a_query_url: READABLE_STRING_8): READABLE_STRING_8
local local
b: like base_url b: like local_base_url
do do
b := base_url b := local_base_url
if b = Void then if b = Void then
b := "" b := ""
end end
@@ -90,24 +126,29 @@ feature {NONE} -- Events
on_clean on_clean
-- <Precursor> -- <Precursor>
do do
if attached web_app as app then if attached web_connector as conn then
app.shutdown shutdown_server (conn)
end end
end end
shutdown_server (conn: attached like web_connector)
do
conn.shutdown_server
end
http_session: detachable HTTP_CLIENT_SESSION http_session: detachable HTTP_CLIENT_SESSION
get_http_session get_http_session
local local
h: LIBCURL_HTTP_CLIENT h: DEFAULT_HTTP_CLIENT
b: like base_url b: like local_base_url
do do
create h.make create h
b := base_url b := local_base_url
if b = Void then if b = Void then
b := "/" b := "/"
end 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 http_session := sess
sess.set_timeout (-1) sess.set_timeout (-1)
sess.set_is_debug (True) sess.set_is_debug (True)
@@ -120,15 +161,24 @@ feature {NONE} -- Events
do do
get_http_session get_http_session
if attached http_session as sess then 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 sess.get (a_url, adapted_context (ctx)) as res then
if attached res.body as l_body then if attached res.body as l_body then
if res.error_occurred 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 else
assert ("Good answer got=%""+l_body+"%" expected=%""+a_expected_body+"%"", l_body.same_string (a_expected_body)) assert ("Good answer got=%""+l_body+"%" expected=%""+a_expected_body+"%"", l_body.same_string (a_expected_body))
end end
else 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 end
end end
@@ -146,18 +196,34 @@ feature {NONE} -- Events
end end
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 do
get_http_session get_http_session
if attached http_session as sess then 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 if
assert ("Good answer got=%""+l_body+"%" expected=%""+a_expected_body+"%"", l_body.same_string (a_expected_body)) 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 else
assert ("Request %""+a_url+"%" failed", False) assert ("Request %""+a_url+"%" failed", False)
end end
end 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 adapted_context (ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_REQUEST_CONTEXT
do do
if ctx /= Void then if ctx /= Void then
@@ -173,6 +239,7 @@ feature -- Test routines
test_get_request_01 test_get_request_01
-- New test routine -- New test routine
do do
assert ("has port", port_number > 0)
get_http_session get_http_session
if attached http_session as sess then if attached http_session as sess then
test_get_request ("get/01", Void, "get-01") test_get_request ("get/01", Void, "get-01")
@@ -199,11 +266,11 @@ feature -- Test routines
s := "This is an uploaded file%NTesting purpose%N" s := "This is an uploaded file%NTesting purpose%N"
f.put_string (s) f.put_string (s)
f.close 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 create ctx.make
ctx.add_form_parameter ("foo", "bar") 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 else
assert ("not_implemented", False) assert ("not_implemented", False)
end end

View File

@@ -32,7 +32,7 @@ feature -- Execution
feature -- Tests feature -- Tests
test_script_url test_script_url_1
local local
req: WSF_REQUEST req: WSF_REQUEST
s: READABLE_STRING_8 s: READABLE_STRING_8
@@ -48,7 +48,13 @@ feature -- Tests
) )
s := req.script_url ("/new/path/") s := req.script_url ("/new/path/")
assert ("script_url (/new/path/) = %""+s+"%" but should be %"/foo/bar/new/path/%"", s.same_string ("/foo/bar/new/path/")) assert ("script_url (/new/path/) = %""+s+"%" but should be %"/foo/bar/new/path/%"", s.same_string ("/foo/bar/new/path/"))
end
test_script_url_2
local
req: WSF_REQUEST
s: READABLE_STRING_8
do
--| Case #2 --| Case #2
req := new_request (<< req := new_request (<<
["REQUEST_METHOD", "GET"], ["REQUEST_METHOD", "GET"],
@@ -60,7 +66,13 @@ feature -- Tests
) )
s := req.script_url ("/new/path/") s := req.script_url ("/new/path/")
assert ("script_url (/new/path/) = %""+s+"%" but should be %"/foo/bar/new/path/%"", s.same_string ("/foo/bar/new/path/")) assert ("script_url (/new/path/) = %""+s+"%" but should be %"/foo/bar/new/path/%"", s.same_string ("/foo/bar/new/path/"))
end
test_script_url_3
local
req: WSF_REQUEST
s: READABLE_STRING_8
do
--| Case #3 --| Case #3
req := new_request (<< req := new_request (<<
["REQUEST_METHOD", "GET"], ["REQUEST_METHOD", "GET"],

View File

@@ -44,17 +44,17 @@ feature -- Test Cases
l_cookie.set_path ("/") l_cookie.set_path ("/")
l_cookie.set_secure (True) l_cookie.set_secure (True)
l_cookie.set_http_only (True) l_cookie.set_http_only (True)
assert("Expected", l_cookie.header_line.same_string ("Set-Cookie: user_id=u12345; Domain=www.example.com; Path=/; Expires=Sat, 18 Apr 2015 21:22:05 GMT; Max-Age=-1; Secure; HttpOnly")) assert("Expected", l_cookie.header_line.same_string ("Set-Cookie: user_id=u12345; Domain=www.example.com; Path=/; Expires=Sat, 18 Apr 2015 21:22:05 GMT; Secure; HttpOnly"))
w_res.put_header_text (l_header.string) w_res.put_header_text (l_header.string)
w_res.add_cookie (l_cookie) w_res.add_cookie (l_cookie)
w_res.set_status_code ({HTTP_STATUS_CODE}.ok) w_res.set_status_code ({HTTP_STATUS_CODE}.ok)
w_res.put_string ("Test") w_res.put_string ("Test")
assert ("Expected", l_res.output.same_string("200 %R%NContent-Type: text/html%R%NSet-Cookie: user_id=u12345; Domain=www.example.com; Path=/; Expires=Sat, 18 Apr 2015 21:22:05 GMT; Max-Age=-1; Secure; HttpOnly%R%N%R%NTest") ) assert ("Expected", l_res.output.same_string("200 %R%NContent-Type: text/html%R%NSet-Cookie: user_id=u12345; Domain=www.example.com; Path=/; Expires=Sat, 18 Apr 2015 21:22:05 GMT; Secure; HttpOnly%R%N%R%NTest") )
end end
test_add_multiple_cookiewith_similar_cookie_name test_add_multiple_cookies_with_similar_cookie_name
local local
w_res: WSF_RESPONSE w_res: WSF_RESPONSE
l_cookie: WSF_COOKIE l_cookie: WSF_COOKIE
@@ -73,7 +73,7 @@ feature -- Test Cases
l_cookie.set_path ("/") l_cookie.set_path ("/")
l_cookie.set_secure (True) l_cookie.set_secure (True)
l_cookie.set_http_only (True) l_cookie.set_http_only (True)
assert("Expected", l_cookie.header_line.same_string ("Set-Cookie: user_id=u12345; Domain=www.example.com; Path=/; Expires=Sat, 18 Apr 2015 21:22:05 GMT; Max-Age=-1; Secure; HttpOnly")) assert("Expected", l_cookie.header_line.same_string ("Set-Cookie: user_id=u12345; Domain=www.example.com; Path=/; Expires=Sat, 18 Apr 2015 21:22:05 GMT; Secure; HttpOnly"))
w_res.put_header_text (l_header.string) w_res.put_header_text (l_header.string)
w_res.add_cookie (l_cookie) w_res.add_cookie (l_cookie)
@@ -84,16 +84,16 @@ feature -- Test Cases
l_cookie.set_path ("/") l_cookie.set_path ("/")
l_cookie.set_secure (True) l_cookie.set_secure (True)
l_cookie.set_http_only (True) l_cookie.set_http_only (True)
assert("Expected", l_cookie.header_line.same_string ("Set-Cookie: user_id=newUser; Domain=www.example.com; Path=/; Expires=Sat, 18 Apr 2015 21:22:05 GMT; Max-Age=-1; Secure; HttpOnly")) assert("Expected", l_cookie.header_line.same_string ("Set-Cookie: user_id=newUser; Domain=www.example.com; Path=/; Expires=Sat, 18 Apr 2015 21:22:05 GMT; Secure; HttpOnly"))
w_res.add_cookie (l_cookie) -- Ignored w_res.add_cookie (l_cookie) -- Ignored
w_res.set_status_code ({HTTP_STATUS_CODE}.ok) w_res.set_status_code ({HTTP_STATUS_CODE}.ok)
w_res.put_string ("Test") w_res.put_string ("Test")
assert ("Expected", l_res.output.same_string("200 %R%NContent-Type: text/html%R%NSet-Cookie: user_id=u12345; Domain=www.example.com; Path=/; Expires=Sat, 18 Apr 2015 21:22:05 GMT; Max-Age=-1; Secure; HttpOnly%R%N%R%NTest") ) assert ("Expected", l_res.output.same_string("200 %R%NContent-Type: text/html%R%NSet-Cookie: user_id=u12345; Domain=www.example.com; Path=/; Expires=Sat, 18 Apr 2015 21:22:05 GMT; Secure; HttpOnly%R%N%R%NTest") )
end end
test_add_multiple_cookie_with_similar_cookie_name_2 test_add_multiple_cookies_with_similar_cookie_name_2
local local
w_res: WSF_RESPONSE w_res: WSF_RESPONSE
l_cookie: WSF_COOKIE l_cookie: WSF_COOKIE
@@ -113,7 +113,7 @@ feature -- Test Cases
l_cookie.set_path ("/") l_cookie.set_path ("/")
l_cookie.set_secure (True) l_cookie.set_secure (True)
l_cookie.set_http_only (True) l_cookie.set_http_only (True)
assert("Expected", l_cookie.header_line.same_string ("Set-Cookie: user_id=u12345; Domain=www.example.com; Path=/; Expires=Sat, 18 Apr 2015 21:22:05 GMT; Max-Age=-1; Secure; HttpOnly")) assert("Expected", l_cookie.header_line.same_string ("Set-Cookie: user_id=u12345; Domain=www.example.com; Path=/; Expires=Sat, 18 Apr 2015 21:22:05 GMT; Secure; HttpOnly"))
w_res.add_cookie (l_cookie) w_res.add_cookie (l_cookie)
@@ -123,7 +123,7 @@ feature -- Test Cases
l_cookie.set_path ("/") l_cookie.set_path ("/")
l_cookie.set_secure (True) l_cookie.set_secure (True)
l_cookie.set_http_only (True) l_cookie.set_http_only (True)
assert("Expected", l_cookie.header_line.same_string ("Set-Cookie: user_id=newUser; Domain=www.example.com; Path=/; Expires=Sat, 18 Apr 2015 21:22:05 GMT; Max-Age=-1; Secure; HttpOnly")) assert("Expected", l_cookie.header_line.same_string ("Set-Cookie: user_id=newUser; Domain=www.example.com; Path=/; Expires=Sat, 18 Apr 2015 21:22:05 GMT; Secure; HttpOnly"))
w_res.add_cookie (l_cookie) -- Ignored w_res.add_cookie (l_cookie) -- Ignored
@@ -134,11 +134,11 @@ feature -- Test Cases
l_cookie.set_path ("/") l_cookie.set_path ("/")
l_cookie.set_secure (True) l_cookie.set_secure (True)
l_cookie.set_http_only (True) l_cookie.set_http_only (True)
assert("Expected", l_cookie.header_line.same_string ("Set-Cookie: ewf_sessionid=test; Domain=www.example.com; Path=/; Expires=Sat, 18 Apr 2015 21:22:05 GMT; Max-Age=-1; Secure; HttpOnly")) assert("Expected", l_cookie.header_line.same_string ("Set-Cookie: ewf_sessionid=test; Domain=www.example.com; Path=/; Expires=Sat, 18 Apr 2015 21:22:05 GMT; Secure; HttpOnly"))
w_res.add_cookie (l_cookie) w_res.add_cookie (l_cookie)
w_res.set_status_code ({HTTP_STATUS_CODE}.ok) w_res.set_status_code ({HTTP_STATUS_CODE}.ok)
w_res.put_string ("Test") w_res.put_string ("Test")
assert ("Expected", l_res.output.same_string("200 %R%NContent-Type: text/html%R%NSet-Cookie: user_id=u12345; Domain=www.example.com; Path=/; Expires=Sat, 18 Apr 2015 21:22:05 GMT; Max-Age=-1; Secure; HttpOnly%R%NSet-Cookie: ewf_sessionid=test; Domain=www.example.com; Path=/; Expires=Sat, 18 Apr 2015 21:22:05 GMT; Max-Age=-1; Secure; HttpOnly%R%N%R%NTest") ) assert ("Expected", l_res.output.same_string("200 %R%NContent-Type: text/html%R%NSet-Cookie: user_id=u12345; Domain=www.example.com; Path=/; Expires=Sat, 18 Apr 2015 21:22:05 GMT; Secure; HttpOnly%R%NSet-Cookie: ewf_sessionid=test; Domain=www.example.com; Path=/; Expires=Sat, 18 Apr 2015 21:22:05 GMT; Secure; HttpOnly%R%N%R%NTest") )
end end
end end

View File

@@ -1,27 +1,27 @@
<?xml version="1.0" encoding="ISO-8859-1"?> <?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"> <target name="server">
<root class="TEST" feature="make"/> <root class="TEST" feature="make"/>
<file_rule> <file_rule>
<exclude>/.git$</exclude> <exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude> <exclude>/.svn$</exclude>
<exclude>/EIFGENs$</exclude>
</file_rule> </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"/> <assertions precondition="true" postcondition="true" check="true" loop="true" supplier_precondition="true"/>
</option> </option>
<setting name="concurrency" value="thread"/> <setting name="concurrency" value="scoop"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <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="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"> <library name="ewsgi" location="..\..\ewsgi\ewsgi-safe.ecf" readonly="false">
<option> <option>
<assertions precondition="true" postcondition="true" check="true" supplier_precondition="true"/> <assertions precondition="true" postcondition="true" check="true" supplier_precondition="true"/>
</option> </option>
</library> </library>
<library name="http" location="..\..\..\network\protocol\http\http-safe.ecf" readonly="false"/> <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="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/> <library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
<library name="wsf" location="..\wsf-safe.ecf" readonly="false"> <library name="wsf" location="..\wsf-safe.ecf" readonly="false">
@@ -29,6 +29,7 @@
<assertions precondition="true" postcondition="true" check="true" supplier_precondition="true"/> <assertions precondition="true" postcondition="true" check="true" supplier_precondition="true"/>
</option> </option>
</library> </library>
<library name="wsf_standalone" location="..\..\wsf\connector\standalone-safe.ecf" readonly="false"/>
<cluster name="server" location=".\server\" recursive="true"/> <cluster name="server" location=".\server\" recursive="true"/>
</target> </target>
<target name="wsf_tests" extends="server"> <target name="wsf_tests" extends="server">

View File

@@ -11,15 +11,16 @@
</option> </option>
<setting name="concurrency" value="thread"/> <setting name="concurrency" value="thread"/>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/> <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="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="ewsgi" location="..\..\ewsgi\ewsgi.ecf" readonly="false"/>
<library name="http" location="..\..\..\network\protocol\http\http.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="thread" location="$ISE_LIBRARY\library\thread\thread.ecf"/>
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/> <library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
<library name="wsf" location="..\wsf.ecf" readonly="false"/> <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"/> <cluster name="server" location=".\server\" recursive="true"/>
</target> </target>
<target name="wsf_tests" extends="server"> <target name="wsf_tests" extends="server">

View File

@@ -85,7 +85,7 @@ def runTestForProject(where):
# compile the restbucks # compile the restbucks
print "# Compiling restbucks example" print "# Compiling restbucks example"
cmd = "ecb -config %s -target restbucks -batch -c_compile -project_path . " % (os.path.join ("examples", "restbucks", "restbucks-safe.ecf")) cmd = "ecb -config %s -target restbucks -batch -c_compile -project_path . " % (os.path.join ("examples", "restbucksCRUD", "restbucks-safe.ecf"))
res = eval_cmd(cmd) res = eval_cmd(cmd)
sleep(1) sleep(1)

View File

@@ -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_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_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_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="launcher" location=".\launcher\" recursive="true">
<cluster name="any_launcher" location="$|any"/> <cluster name="any_launcher" location="$|any"/>
</cluster> </cluster>
@@ -35,16 +34,6 @@
</cluster> </cluster>
<cluster name="src" location=".\src\" recursive="true"/> <cluster name="src" location=".\src\" recursive="true"/>
</target>{/if} </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"} {if condition="$WIZ.connectors.use_cgi ~ $WIZ_YES"}
<target name="{$WIZ.project.name/}_cgi" extends="common"> <target name="{$WIZ.project.name/}_cgi" extends="common">
<root class="{$APP_ROOT/}" feature="make_and_launch"/> <root class="{$APP_ROOT/}" feature="make_and_launch"/>

View File

@@ -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/} port={$WIZ.standalone_connector.port/}
#verbose=true #verbose=true

View File

@@ -31,7 +31,7 @@ feature -- Execution
-- Choose a default -> standalone -- Choose a default -> standalone
create {WSF_STANDALONE_SERVICE_LAUNCHER} launcher.make_and_launch (opts){/literal}{/if} create {WSF_STANDALONE_SERVICE_LAUNCHER} launcher.make_and_launch (opts){/literal}{/if}
{if condition="$WIZ.connectors.use_standalone ~ $WIZ_YES"}{literal} {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} create {WSF_STANDALONE_SERVICE_LAUNCHER} launcher.make_and_launch (opts){/literal}{/if}
{if condition="$WIZ.connectors.use_libfcgi ~ $WIZ_YES"}{literal} {if condition="$WIZ.connectors.use_libfcgi ~ $WIZ_YES"}{literal}
elseif is_libfcgi_launcher_id (l_id) then elseif is_libfcgi_launcher_id (l_id) then
@@ -39,9 +39,9 @@ feature -- Execution
{if condition="$WIZ.connectors.use_cgi ~ $WIZ_YES"}{literal} {if condition="$WIZ.connectors.use_cgi ~ $WIZ_YES"}{literal}
elseif is_cgi_launcher_id (l_id) then elseif is_cgi_launcher_id (l_id) then
create {WSF_CGI_SERVICE_LAUNCHER} launcher.make_and_launch (opts){/literal}{/if} create {WSF_CGI_SERVICE_LAUNCHER} launcher.make_and_launch (opts){/literal}{/if}
{if condition="$WIZ.connectors.use_nino ~ $WIZ_YES"}{literal} {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_NINO_SERVICE_LAUNCHER} launcher.make_and_launch (opts){/literal}{/if} create {WSF_STANDALONE_SERVICE_LAUNCHER} launcher.make_and_launch (opts){/literal}{/if}
{literal} {literal}
else else
io.error.put_string ("Application launcher not found!%N") io.error.put_string ("Application launcher not found!%N")
@@ -52,7 +52,7 @@ feature -- Execution
launcher_id: detachable READABLE_STRING_GENERAL launcher_id: detachable READABLE_STRING_GENERAL
-- Launcher id based on the executable extension name if any. -- Launcher id based on the executable extension name if any.
-- This can be redefine to customize for your application. -- This can be redefine to customize for your application.
--| ex: nino, cgi, libfcgi or Void. --| ex: standalone, cgi, libfcgi or Void.
do do
if attached (create {PATH}.make_from_string (execution_environment.arguments.command_name)).extension as ext then if attached (create {PATH}.make_from_string (execution_environment.arguments.command_name)).extension as ext then
Result := ext Result := ext
@@ -62,17 +62,11 @@ feature -- Execution
feature -- Status report feature -- Status report
{/literal} {/literal}
{if condition="$WIZ.connectors.use_standalone ~ $WIZ_YES"} {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 do
Result := a_id.is_case_insensitive ("standalone") Result := a_id.is_case_insensitive ("standalone")
end{/if} 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"} {if condition="$WIZ.connectors.use_cgi ~ $WIZ_YES"}
is_cgi_launcher_id (a_id: READABLE_STRING_GENERAL): BOOLEAN is_cgi_launcher_id (a_id: READABLE_STRING_GENERAL): BOOLEAN
do do

Some files were not shown because too many files have changed in this diff Show More