Compare commits

..

23 Commits

Author SHA1 Message Date
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
b4fd04ad9f Updated has_incoming_data comment. 2016-10-05 16:19:48 +02:00
71a98f3c28 Make EiffelWeb standalone easier to debug by using in some locations error instead of exception for network error.
- Added C external to use C `recv` feature with error (as opposed to have exception raised on network error).
2016-10-05 10:45:57 +02:00
ed22be2551 Commented the execute_bad_request, since it is not ready and will trigger error most of the time. 2016-10-05 00:04:21 +02:00
77085364ee Improve socket management for EiffelWeb standalone connector. 2016-10-04 18:49:48 +02:00
0217c6d3f4 First attempt to response with bad request message when bad request is detected. 2016-10-04 13:00:38 +02:00
55fec2423c Added ssl test case for standalone wsf connector. 2016-10-04 12:59:56 +02:00
1f7a81a2d6 Updated workbook, minor changes (removed mention about nino, added libfcgi info). 2016-10-04 12:56:11 +02:00
612ff243c1 Also display SSL information when verbose is enabled for EiffelWeb standalone connector. 2016-10-02 20:05:44 +02:00
40fb3893af Include wsf_proxy to the installation process. 2016-09-27 16:18:06 +02:00
21407f8dcf Fixed SSL support on the httpd component, and also on the EiffelWeb standalone connector.
- the standalone connector support for SSL, is using certicate files for now (no in-memory support).
  - to enable ssl support, set ecf variable `httpd_ssl_enabled=true`.
  - added the `simple_ssl` example to demonstrate how to have standalone ssl server.
    (be careful when using EiffelNet SSL and the http_client library, disable the libcurl
      via ecf variable `libcurl_http_client_disabled=true` )

Added support for recv timeout to the EiffelWeb standalone connector.
  - made EiffelWeb compilable with 16.05 and upcoming 16.11.
    Done via ecfs condition on version to accept EiffelNet with recv_timeout (from 16.11), and without (until 16.05).
  - adding recv timeout prevents server to hang for ever if a client wait too long to send data.

Updated various comments.
2016-09-27 16:11:47 +02:00
356eb143ea Fixed the non void-safe ecf for wsf_proxy. 2016-09-26 17:42:49 +02:00
df551d4a4f Use latest API from http_client using DEFAULT_HTTP_CLIENT,
that could use libcurl or EiffelNet depending on the configuration (.ecf).
2016-09-26 13:13:57 +02:00
f010da04e9 Merge branch 'reverse_proxy' 2016-09-19 22:19:21 +02:00
5029049ef0 Replaced host+port by uri (http://remotemachine:port/path).
Added support for SSL (https).
2016-08-08 12:30:28 +02:00
210fae5000 First step towards SSL support. 2016-08-06 10:04:45 +02:00
9cc9b95190 Added a simple reverse proxy handler.
- For now, it does not support SSL connection on the target yet.
- No external config file support, this is all about coding.
2016-08-05 11:38:35 +02:00
118 changed files with 2527 additions and 1100 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")
@@ -101,7 +101,6 @@ Other connectors:
**WSF_STANDALONE_SERVICE_LAUNCHER** **WSF_STANDALONE_SERVICE_LAUNCHER**
**WSF_CGI_SERVICE_LAUNCHER** **WSF_CGI_SERVICE_LAUNCHER**
**WSF_NINO_SERVICE_LAUNCHER**
**WSF_LIBFCGI_SERVICE_LAUNCHER** **WSF_LIBFCGI_SERVICE_LAUNCHER**
A basic EWF service inherits from **WSF_DEFAULT_SERVICE**, which has a formal generic that should conform to **WSF_EXECUTION** class with a `make' creation procedure, in our case the class **APPLICATION_EXECUTION**. A basic EWF service inherits from **WSF_DEFAULT_SERVICE**, which has a formal generic that should conform to **WSF_EXECUTION** class with a `make' creation procedure, in our case the class **APPLICATION_EXECUTION**.
@@ -150,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>
@@ -205,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,7 +13,7 @@ EWF Deployment
4. Deploying EWF FCGI 4. Deploying EWF FCGI
5. FCGI overview 5. FCGI overview
1. Build EWF application 1. Build EWF application
2. Copy the generated exe file and the www content.htaccess CGI 2. Copy the generated exe file and the www content.htaccess CGI
@@ -25,10 +25,14 @@ EWF Deployment
>Apache Version: Apache 2.4.4 >Apache Version: Apache 2.4.4
>Windows: http://www.apachelounge.com/download/ >Windows: http://www.apachelounge.com/download/
note: on linux (debian), use
> sudo apt-get install apache2
#### Deploying EWF CGI #### Deploying EWF CGI
#### CGI overview #### CGI overview
>A new process is started for each HTTP request. So if there are N requests to the same >CGI program, the code of the CGI program is loaded into memory N times. >A new process is started for each HTTP request. So if there are N requests to the same
>CGI program, the code of the CGI program is loaded into memory N times.
>When a CGI program finishes handling a request, the program terminates. >When a CGI program finishes handling a request, the program terminates.
* Build EWF application * Build EWF application
@@ -95,6 +99,9 @@ Check that you have the following modules enabled
>To deploy FCGI you will need to download the mod_fcgi module. >To deploy FCGI you will need to download the mod_fcgi module.
>You can get it from here http://www.apachelounge.com/download/ >You can get it from here http://www.apachelounge.com/download/
note: on linux (debian), use
> sudo apt-get install libapache2-mod-fastcgi
#### FCGI overview #### FCGI overview
>FastCGI allows a single, long-running process to handle more than one user request while keeping close to the CGI programming model, retaining the simplicity while eliminating the overhead of creating a new process for each request. Unlike converting an application to a web server plug-in, FastCGI applications remain independent of the web server. >FastCGI allows a single, long-running process to handle more than one user request while keeping close to the CGI programming model, retaining the simplicity while eliminating the overhead of creating a new process for each request. Unlike converting an application to a web server plug-in, FastCGI applications remain independent of the web server.
@@ -128,6 +135,22 @@ Copy the app.exe and the folder "www" into a folder served by apache2, for exam
>NOTE: By default Apache does not come with fcgid module, so you will need to download it, and put the module under Apache2/modules >NOTE: By default Apache does not come with fcgid module, so you will need to download it, and put the module under Apache2/modules
It is also possible to set various parameters in the apache site configuration file such as:
```
<IfModule mod_fcgid.c>
# FcgidIdleTimeout 600
# FcgidBusyScanInterval 120
# FcgidProcessLifeTime 3600
# FcgidMaxProcesses 5
# FcgidMaxProcessesPerClass 100
# FcgidMinProcessesPerClass 100
# FcgidConnectTimeout 8
# FcgidIOTimeout 60
# FcgidBusyTimeout 1200
</IfModule>
```
See https://httpd.apache.org/mod_fcgid/mod/mod_fcgid.html for more information.
# .htaccess FCGI # .htaccess FCGI
``` ```

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

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

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

@@ -0,0 +1,29 @@
note
description: "Launcher for reverse proxy web application."
date: "$Date$"
revision: "$Revision$"
class
APPLICATION
inherit
WSF_DEFAULT_SERVICE [APPLICATION_EXECUTION]
redefine
initialize
end
create
make_and_launch
feature {NONE} -- Initialization
initialize
-- Initialize current service.
do
-- Specific to `standalone' connector (the EiffelWeb server).
-- See `{WSF_STANDALONE_SERVICE_LAUNCHER}.initialize'
set_service_option ("port", 9090)
import_service_options (create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI}.make_from_file ("server.ini"))
end
end

View File

@@ -0,0 +1,49 @@
note
description: "Reverse proxy example."
date: "$Date$"
revision: "$Revision$"
class
APPLICATION_EXECUTION
inherit
WSF_EXECUTION
WSF_URI_REWRITER
rename
uri as proxy_uri
end
create
make
feature -- Basic operations
execute
do
-- NOTE: please enter the target server uri here
-- replace "http://localhost:8080/foobar"
send_proxy_response ("http://localhost:8080/foobar", Current)
end
send_proxy_response (a_remote: READABLE_STRING_8; a_rewriter: detachable WSF_URI_REWRITER)
local
h: WSF_SIMPLE_REVERSE_PROXY_HANDLER
do
create h.make (a_remote)
h.set_uri_rewriter (a_rewriter)
h.set_uri_rewriter (create {WSF_AGENT_URI_REWRITER}.make (agent proxy_uri))
h.set_timeout (30) -- 30 seconds
h.set_connect_timeout (5_000) -- milliseconds = 5 seconds
h.execute (request, response)
end
feature -- Helpers
proxy_uri (a_request: WSF_REQUEST): STRING
-- Request uri rewriten as url.
do
Result := a_request.request_uri
end
end

28
examples/proxy/proxy.ecf Normal file
View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<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="proxy" uuid="B55F0D95-3793-4C90-BBAC-BF5F2DECD5E6" library_target="proxy">
<target name="common" abstract="true">
<file_rule>
<exclude>/.svn$</exclude>
<exclude>/CVS$</exclude>
<exclude>/EIFGENs$</exclude>
</file_rule>
<option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="transitional" syntax="transitional">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="console_application" value="true"/>
<variable name="ssl_supported" value="false"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="http" location="..\..\library\network\protocol\http\http-safe.ecf"/>
<library name="wsf" location="..\..\library\server\wsf\wsf-safe.ecf"/>
<library name="wsf_proxy" location="..\..\library\server\wsf_proxy\wsf_proxy-safe.ecf" readonly="false"/>
</target>
<target name="proxy" extends="common">
<root class="APPLICATION" feature="make_and_launch"/>
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="concurrency" value="scoop"/>
<library name="default_standalone" location="..\..\library\server\wsf\default\standalone-safe.ecf"/>
<cluster name="proxy" location=".\" recursive="true"/>
</target>
</system>

View File

@@ -0,0 +1,8 @@
verbose=true
verbose_level=ALERT
port=9090
#max_concurrent_connections=100
#keep_alive_timeout=15
#max_tcp_clients=100
#socket_timeout=300
#max_keep_alive_requests=300

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

@@ -24,6 +24,8 @@ feature -- Basic operations
s := "Hello World!" s := "Hello World!"
create dt.make_now_utc create dt.make_now_utc
s.append (" (UTC time is " + dt.rfc850_string + ").") s.append (" (UTC time is " + dt.rfc850_string + ").")
s.append ("%N")
s.append ("Your request: " + request.request_uri + " %N")
response.put_header ({HTTP_STATUS_CODE}.ok, <<["Content-Type", "text/html"], ["Content-Length", s.count.out]>>) response.put_header ({HTTP_STATUS_CODE}.ok, <<["Content-Type", "text/html"], ["Content-Length", s.count.out]>>)
response.set_status_code ({HTTP_STATUS_CODE}.ok) response.set_status_code ({HTTP_STATUS_CODE}.ok)
response.header.put_content_type_text_html response.header.put_content_type_text_html

View File

@@ -0,0 +1,29 @@
note
description : "simple application root class"
date : "$Date$"
revision : "$Revision$"
class
APPLICATION
inherit
WSF_DEFAULT_SERVICE [APPLICATION_EXECUTION]
redefine
initialize
end
create
make_and_launch
feature {NONE} -- Initialization
initialize
-- Initialize current service.
do
-- Specific to `standalone' connector (the EiffelWeb server).
-- See `{WSF_STANDALONE_SERVICE_LAUNCHER}.initialize'
set_service_option ("port", 9090)
import_service_options (create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI}.make_from_file ("simple.ini"))
end
end

View File

@@ -0,0 +1,41 @@
note
description : "simple application execution"
date : "$Date$"
revision : "$Revision$"
class
APPLICATION_EXECUTION
inherit
WSF_EXECUTION
create
make
feature -- Basic operations
execute
local
s: STRING
dt: HTTP_DATE
do
-- To send a response we need to setup, the status code and
-- the response headers.
s := "Hello World!"
create dt.make_now_utc
s.append (" (UTC time is " + dt.rfc850_string + ").")
if request.is_https then
s.append ("<p>This is a secured connection! (https)</p>%N")
end
response.put_header ({HTTP_STATUS_CODE}.ok, <<["Content-Type", "text/html"], ["Content-Length", s.count.out]>>)
response.set_status_code ({HTTP_STATUS_CODE}.ok)
response.header.put_content_type_text_html
response.header.put_content_length (s.count)
if attached request.http_connection as l_connection and then l_connection.is_case_insensitive_equal_general ("keep-alive") then
response.header.put_header_key_value ("Connection", "keep-alive")
end
response.put_string (s)
end
end

View File

@@ -0,0 +1,15 @@
-----BEGIN CERTIFICATE-----
MIICWDCCAcGgAwIBAgIJAJnXGtV+PtiYMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTUwNDAzMjIxNTA0WhcNMTYwNDAyMjIxNTA0WjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
gQDFMK6ojzg+KlklhTossR13c51izMgGc3B0z9ttfHIcx2kxra3HtHcKIl5wSUvn
G8zmSyFAyQTs5LUv65q46FM9qU8tP+vTeFCfNXvjRcIEpouta3J53K0xuUlxz4d4
4D6qvdDWAez/0AkI4y5etW5zXtg7IQorJhsI9TmfGuruzwIDAQABo1AwTjAdBgNV
HQ4EFgQUbWpk2HoHa0YqpEwr7CGEatBFTMkwHwYDVR0jBBgwFoAUbWpk2HoHa0Yq
pEwr7CGEatBFTMkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQAi+h4/
IgEocWkdRZBKHEcTrRxz5WhEDJMoVo9LhnXvCfn1G/4p6Un6sYv7Xzpi9NuSY8uV
cjfJJXhtF3AtyZ70iTAxWaRWjGaZ03PYOjlledJ5rqJEt6CCn8m+JsfznduZvbxQ
zQ6jCLXfyD/tvemB+yYEI3NntvRKx5/zt6Q26Q==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,28 @@
##########################################################
### EiffelWeb settings for related connector ###
### Mostly for EiffelWeb standalone connector ###
### See {WGI_STANDALONE_CONSTANTS} for default values. ###
##########################################################
### Connection settings
port=9090
#max_concurrent_connections=100
#max_tcp_clients=100
### Timeout settings
#socket_timeout=60
#socket_recv_timeout=5
### Persistent connection settings
#keep_alive_timeout=15
#max_keep_alive_requests=100
### SSL settings
# enable SSL, with file certificate.
ssl_enabled=true
ssl_ca_key=simple.key
ssl_ca_crt=simple.crt
### App settings
verbose=true
verbose_level=ALERT

View File

@@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDFMK6ojzg+KlklhTossR13c51izMgGc3B0z9ttfHIcx2kxra3H
tHcKIl5wSUvnG8zmSyFAyQTs5LUv65q46FM9qU8tP+vTeFCfNXvjRcIEpouta3J5
3K0xuUlxz4d44D6qvdDWAez/0AkI4y5etW5zXtg7IQorJhsI9TmfGuruzwIDAQAB
AoGAR5efMg+dieRyLU8rieJcImxVbfOPg9gRsjdtIVkXTR+RL7ow59q7hXBo/Td/
WU8cm1gXoJ/bK+71YYqWyB+BaLRIWvRWb7Gdw203tu4e136Ca5uuY+71qdbVTVcl
NQ7J+T+eAQFP+a+DdT3ZQxu9eze87SMbu6i5YSpIk2kusOECQQDunv/DQ+nc+NgR
DF+Td3sNYUVRT9a1CWi6abAG6reXwp8MS4NobWDf+Ps4JODhEEwlIdq5qL7qqYBZ
Gc1TJJ53AkEA0404Fn6vAzzegBcS4RLlYTK7nMr0m4pMmDMCI6YzAYdMmKHp1e6f
IwxSmQrmwyAgwcT01bc0+A8yipcC2BWQaQJBAJ01QZm635OGmos41KsKF5bsE8gL
SpBBH69Yu/ECqGwie7iU84FUNnO4zIHjwghlPVVlZX3Vz9o4S+fn2N9DC+cCQGyZ
QyCxGdC0r5fbwHJQS/ZQn+UGfvlVzqoXDVMVn3t6ZES6YZrT61eHnOM5qGqklIxE
Old3vDZXPt/MU8Zvk3kCQBOgUx2VxvTrHN37hk9/QIDiM62+RenBm1M3ah8xTosf
1mSeEb6d9Kwb3TgPBmA7YXzJuAQfRIvEPMPxT5SSr6Q=
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<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="simple_ssl" uuid="C2FE296C-3C18-4609-A5AB-F604BDEE4410" library_target="simple_ssl">
<target name="simple_ssl">
<description>Simple EiffelWeb standalone server with SSL support (Concurrent connection supported thanks to SCOOP).</description>
<root class="APPLICATION" feature="make_and_launch"/>
<file_rule>
<exclude>/.svn$</exclude>
<exclude>/CVS$</exclude>
<exclude>/EIFGENs$</exclude>
</file_rule>
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
<assertions/>
</option>
<setting name="console_application" value="true"/>
<setting name="concurrency" value="scoop"/>
<variable name="httpd_ssl_enabled" value="true"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="default_standalone" location="..\..\library\server\wsf\default\standalone-safe.ecf"/>
<library name="http" location="..\..\library\network\protocol\http\http-safe.ecf"/>
<library name="wsf" location="..\..\library\server\wsf\wsf-safe.ecf"/>
<cluster name="simple" location=".\" recursive="true"/>
</target>
<target name="simple_ssl_st" extends="simple_ssl">
<description>Simple EiffelWeb standalone server with SSL support (Single threaded, thus no concurrent connection.)</description>
<setting name="concurrency" value="none"/>
</target>
</system>

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

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

@@ -508,9 +508,9 @@ feature -- Helper
new_session (a_uri: READABLE_STRING_8): HTTP_CLIENT_SESSION new_session (a_uri: READABLE_STRING_8): HTTP_CLIENT_SESSION
local local
cl: LIBCURL_HTTP_CLIENT cl: DEFAULT_HTTP_CLIENT
do do
create cl.make create cl
Result := cl.new_session (a_uri) Result := cl.new_session (a_uri)
Result.set_is_insecure (True) Result.set_is_insecure (True)
Result.set_max_redirects (5) Result.set_max_redirects (5)

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

@@ -25,20 +25,27 @@ feature {CONCURRENT_POOL, HTTPD_CONNECTION_HANDLER_I} -- Basic operation
release release
-- <Precursor> -- <Precursor>
local local
d: STRING d: detachable STRING
do do
if attached internal_client_socket as l_socket then
d := l_socket.descriptor.out
else
d := "N/A"
end
debug ("dbglog") debug ("dbglog")
if
attached internal_client_socket as l_socket and then
l_socket.descriptor_available
then
d := l_socket.descriptor.out
else
d := "N/A"
end
dbglog (generator + ".release: ENTER {" + d + "}") dbglog (generator + ".release: ENTER {" + d + "}")
end end
Precursor {HTTPD_REQUEST_HANDLER_I} Precursor {HTTPD_REQUEST_HANDLER_I}
release_pool_item release_pool_item
debug ("dbglog") debug ("dbglog")
dbglog (generator + ".release: LEAVE {" + d + "}") if d /= Void then
dbglog (generator + ".release: LEAVE {" + d + "}")
else
dbglog (generator + ".release: LEAVE {N/A}")
end
end end
end end

View File

@@ -18,21 +18,28 @@ inherit
feature {HTTPD_CONNECTION_HANDLER_I} -- Basic operation feature {HTTPD_CONNECTION_HANDLER_I} -- Basic operation
release release
-- <Precursor>
local local
d: STRING d: detachable STRING
do do
-- FIXME: for log purpose
if attached internal_client_socket as l_socket then
d := l_socket.descriptor.out
else
d := "N/A"
end
debug ("dbglog") debug ("dbglog")
if
attached internal_client_socket as l_socket and then
l_socket.descriptor_available
then
d := l_socket.descriptor.out
else
d := "N/A"
end
dbglog (generator + ".release: ENTER {" + d + "}") dbglog (generator + ".release: ENTER {" + d + "}")
end end
Precursor {HTTPD_REQUEST_HANDLER_I} Precursor {HTTPD_REQUEST_HANDLER_I}
debug ("dbglog") debug ("dbglog")
dbglog (generator + ".release: LEAVE {" + d + "}") if d /= Void then
dbglog (generator + ".release: LEAVE {" + d + "}")
else
dbglog (generator + ".release: LEAVE {N/A}")
end
end end
end end

View File

@@ -6,6 +6,11 @@ note
deferred class deferred class
HTTPD_CONFIGURATION_I HTTPD_CONFIGURATION_I
inherit
ANY
HTTPD_CONSTANTS
feature {NONE} -- Initialization feature {NONE} -- Initialization
make make
@@ -14,6 +19,7 @@ feature {NONE} -- Initialization
max_concurrent_connections := default_max_concurrent_connections max_concurrent_connections := default_max_concurrent_connections
max_tcp_clients := default_max_tcp_clients max_tcp_clients := default_max_tcp_clients
socket_timeout := default_socket_timeout socket_timeout := default_socket_timeout
socket_recv_timeout := default_socket_recv_timeout
keep_alive_timeout := default_keep_alive_timeout keep_alive_timeout := default_keep_alive_timeout
max_keep_alive_requests := default_max_keep_alive_requests max_keep_alive_requests := default_max_keep_alive_requests
is_secure := False is_secure := False
@@ -21,15 +27,6 @@ feature {NONE} -- Initialization
create ca_key.make_empty create ca_key.make_empty
end end
feature -- Defaults
default_http_server_port: INTEGER = 80
default_max_concurrent_connections: INTEGER = 100
default_max_tcp_clients: INTEGER = 100
default_socket_timeout: INTEGER = 300 -- seconds
default_keep_alive_timeout: INTEGER = 15 -- seconds
default_max_keep_alive_requests: INTEGER = 100
feature -- Access feature -- Access
Server_details: STRING_8 Server_details: STRING_8
@@ -45,7 +42,12 @@ feature -- Access
socket_timeout: INTEGER assign set_socket_timeout socket_timeout: INTEGER assign set_socket_timeout
-- Amount of seconds that the server waits for receipts and transmissions during communications. -- Amount of seconds that the server waits for receipts and transmissions during communications.
-- note: with timeout of 0, socket can wait for ever. -- note: with timeout of 0, socket can wait for ever.
-- By default: 300 seconds, which is appropriate for most situations. -- By default: 60 seconds, which is appropriate for most situations.
socket_recv_timeout: INTEGER assign set_socket_recv_timeout
-- Amount of seconds that the server waits for receiving data during communications.
-- note: with timeout of 0, socket can wait for ever.
-- By default: 5 seconds.
max_concurrent_connections: INTEGER assign set_max_concurrent_connections max_concurrent_connections: INTEGER assign set_max_concurrent_connections
-- Max number of concurrent connections. -- Max number of concurrent connections.
@@ -83,8 +85,10 @@ feature -- Access
Result.is_verbose := is_verbose Result.is_verbose := is_verbose
Result.verbose_level := verbose_level Result.verbose_level := verbose_level
Result.timeout := socket_timeout Result.timeout := socket_timeout
Result.socket_recv_timeout := socket_recv_timeout
Result.keep_alive_timeout := keep_alive_timeout Result.keep_alive_timeout := keep_alive_timeout
Result.max_keep_alive_requests := max_keep_alive_requests Result.max_keep_alive_requests := max_keep_alive_requests
Result.is_secure := is_secure
end end
feature -- Access: SSL feature -- Access: SSL
@@ -92,10 +96,10 @@ feature -- Access: SSL
is_secure: BOOLEAN is_secure: BOOLEAN
-- Is SSL/TLS session?. -- Is SSL/TLS session?.
ca_crt: IMMUTABLE_STRING_8 ca_crt: detachable IMMUTABLE_STRING_32
-- the signed certificate. -- the signed certificate.
ca_key: IMMUTABLE_STRING_8 ca_key: detachable IMMUTABLE_STRING_32
-- private key to the certificate. -- private key to the certificate.
ssl_protocol: NATURAL ssl_protocol: NATURAL
@@ -103,6 +107,22 @@ feature -- Access: SSL
feature -- Element change feature -- Element change
set_ssl_settings (v: detachable separate TUPLE [protocol: separate READABLE_STRING_GENERAL; ca_crt, ca_key: detachable separate READABLE_STRING_GENERAL])
local
prot: STRING_32
do
is_secure := False
ca_crt := Void
ca_key := Void
if v /= Void then
is_secure := True
create prot.make_from_separate (v.protocol)
set_ssl_protocol_from_string (prot)
set_ca_crt (v.ca_crt)
set_ca_key (v.ca_key)
end
end
set_http_server_name (v: detachable separate READABLE_STRING_8) set_http_server_name (v: detachable separate READABLE_STRING_8)
do do
if v = Void then if v = Void then
@@ -152,6 +172,14 @@ feature -- Element change
socket_timeout_set: socket_timeout = a_nb_seconds socket_timeout_set: socket_timeout = a_nb_seconds
end end
set_socket_recv_timeout (a_nb_seconds: like socket_recv_timeout)
-- Set `socket_recv_timeout' with `a_nb_seconds'
do
socket_recv_timeout := a_nb_seconds
ensure
socket_recv_timeout_set: socket_recv_timeout = a_nb_seconds
end
set_keep_alive_timeout (a_seconds: like keep_alive_timeout) set_keep_alive_timeout (a_seconds: like keep_alive_timeout)
-- Set `keep_alive_timeout' with `a_seconds' -- Set `keep_alive_timeout' with `a_seconds'
do do
@@ -198,17 +226,33 @@ feature -- Element change
verbose_level_set: verbose_level = lev verbose_level_set: verbose_level = lev
end end
mark_secure set_is_secure (b: BOOLEAN)
-- Set is_secure in True -- Set `is_secure' to `b'.
do do
if has_ssl_support then if b and has_ssl_support then
is_secure := True is_secure := True
if http_server_port = 80 then if
http_server_port = 80
then
set_http_server_port (443) set_http_server_port (443)
end end
else else
is_secure := False is_secure := False
if
http_server_port = 443
then
set_http_server_port (80)
end
end end
ensure
is_secure_set: has_ssl_support implies is_secure
is_not_secure: not has_ssl_support implies not is_secure
end
mark_secure
-- Set is_secure in True
do
set_is_secure (True)
ensure ensure
is_secure_set: has_ssl_support implies is_secure is_secure_set: has_ssl_support implies is_secure
-- http_server_port_set: has_ssl_support implies http_server_port = 443 -- http_server_port_set: has_ssl_support implies http_server_port = 443
@@ -218,16 +262,24 @@ feature -- Element change
feature -- Element change feature -- Element change
set_ca_crt (a_value: separate READABLE_STRING_8) set_ca_crt (a_value: detachable separate READABLE_STRING_GENERAL)
-- Set `ca_crt' from `a_value'. -- Set `ca_crt' from `a_value'.
do do
create ca_crt.make_from_separate (a_value) if a_value /= Void then
create ca_crt.make_from_separate (a_value)
else
ca_crt := Void
end
end end
set_ca_key (a_value: separate READABLE_STRING_8) set_ca_key (a_value: detachable separate READABLE_STRING_GENERAL)
-- Set `ca_key' with `a_value'. -- Set `ca_key' with `a_value'.
do do
create ca_key.make_from_separate (a_value) if a_value /= Void then
create ca_key.make_from_separate (a_value)
else
ca_key := Void
end
end end
set_ssl_protocol (a_version: NATURAL) set_ssl_protocol (a_version: NATURAL)
@@ -238,6 +290,24 @@ feature -- Element change
ssl_protocol_set: ssl_protocol = a_version ssl_protocol_set: ssl_protocol = a_version
end end
set_ssl_protocol_from_string (a_ssl_version: READABLE_STRING_GENERAL)
-- Set `ssl_protocol' with `a_ssl_version'
do
if a_ssl_version.is_case_insensitive_equal ("ssl_2_3") then
set_ssl_protocol_to_ssl_2_or_3
elseif a_ssl_version.is_case_insensitive_equal ("tls_1_0") then
set_ssl_protocol_to_tls_1_0
elseif a_ssl_version.is_case_insensitive_equal ("tls_1_1") then
set_ssl_protocol_to_tls_1_1
elseif a_ssl_version.is_case_insensitive_equal ("tls_1_2") then
set_ssl_protocol_to_tls_1_2
elseif a_ssl_version.is_case_insensitive_equal ("dtls_1_0") then
set_ssl_protocol_to_dtls_1_0
else -- Default
set_ssl_protocol_to_tls_1_2
end
end
feature -- SSL Helpers feature -- SSL Helpers
set_ssl_protocol_to_ssl_2_or_3 set_ssl_protocol_to_ssl_2_or_3

View File

@@ -0,0 +1,28 @@
note
description: "[
Various constant values used in httpd settings.
]"
author: "$Author$"
date: "$Date$"
revision: "$Revision$"
deferred class
HTTPD_CONSTANTS
feature -- Default connection settings
default_http_server_port: INTEGER = 80
default_max_concurrent_connections: INTEGER = 100
default_max_tcp_clients: INTEGER = 100
feature -- Default timeout settings
default_socket_timeout: INTEGER = 60 -- seconds
default_socket_recv_timeout: INTEGER = 5 -- seconds
feature -- Default persistent connection settings
default_keep_alive_timeout: INTEGER = 15 -- seconds
default_max_keep_alive_requests: INTEGER = 100
end

View File

@@ -17,9 +17,15 @@ feature -- Access
verbose_level: INTEGER assign set_verbose_level verbose_level: INTEGER assign set_verbose_level
-- Verbosity of output. -- Verbosity of output.
is_secure: BOOLEAN assign set_is_secure
-- Is using secure connection? i.e SSL?
timeout: INTEGER assign set_timeout timeout: INTEGER assign set_timeout
-- Amount of seconds that the server waits for receipts and transmissions during communications. -- Amount of seconds that the server waits for receipts and transmissions during communications.
socket_recv_timeout: INTEGER assign set_socket_recv_timeout
-- Amount of seconds that the server waits for receiving data on socket during communications.
keep_alive_timeout: INTEGER assign set_keep_alive_timeout keep_alive_timeout: INTEGER assign set_keep_alive_timeout
-- Keep-alive timeout, also known as persistent-connection timeout. -- Keep-alive timeout, also known as persistent-connection timeout.
-- Number of seconds the server waits after a request has been served before it closes the connection. -- Number of seconds the server waits after a request has been served before it closes the connection.
@@ -42,12 +48,24 @@ feature -- Change
verbose_level := lev verbose_level := lev
end end
set_is_secure (b: BOOLEAN)
-- Set `is_secure' to `b'.
do
is_secure := b
end
set_timeout (a_timeout_in_seconds: INTEGER) set_timeout (a_timeout_in_seconds: INTEGER)
-- Set `timeout' to `a_timeout_in_seconds'. -- Set `timeout' to `a_timeout_in_seconds'.
do do
timeout := a_timeout_in_seconds timeout := a_timeout_in_seconds
end end
set_socket_recv_timeout (a_timeout_in_seconds: INTEGER)
-- Set `socket_recv_timeout' to `a_timeout_in_seconds'.
do
socket_recv_timeout := a_timeout_in_seconds
end
set_keep_alive_timeout (a_timeout_in_seconds: INTEGER) set_keep_alive_timeout (a_timeout_in_seconds: INTEGER)
-- Set `keep_alive_timeout' to `a_timeout_in_seconds'. -- Set `keep_alive_timeout' to `a_timeout_in_seconds'.
do do

View File

@@ -10,20 +10,44 @@
<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>
<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="net" location="$ISE_LIBRARY\library\net\net-safe.ecf"/> <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">
<condition> <condition>
<custom name="net_ssl_enabled" value="true"/> <custom name="net_ssl_enabled" value="true"/>
</condition> </condition>
</library> </library>
<cluster name="network" location=".\network" recursive="false"> <cluster name="network" location=".\network\">
<cluster name="ssl_network" location="$|ssl" recursive="true"> <file_rule>
<exclude>/httpd_stream_socket_ext.e$</exclude>
<condition> <condition>
<custom name="net_ssl_enabled" value="true"/> <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> </condition>
</cluster> </cluster>
</cluster> </cluster>
</target> </target>
</system> </system>

View File

@@ -19,9 +19,33 @@
</condition> </condition>
</library> </library>
<cluster name="network" location=".\network\"> <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"> <cluster name="ssl_network" location="$|ssl\" recursive="true">
<condition> <condition>
<custom name="net_ssl_enabled" value="true"/> <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,19 +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>
<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>
@@ -64,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

@@ -23,11 +23,35 @@
</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="network" location=".\network\">
<cluster name="ssl_network" location="$|ssl" recursive="true"> <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> <condition>
<custom name="httpd_ssl_enabled" value="true"/> <custom name="httpd_ssl_enabled" value="true"/>
</condition> </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>
</cluster> </cluster>
<cluster name="httpd_server" location=".\" recursive="true"> <cluster name="httpd_server" location=".\" recursive="true">

View File

@@ -11,6 +11,8 @@ inherit
HTTPD_LOGGER_CONSTANTS HTTPD_LOGGER_CONSTANTS
HTTPD_SOCKET_FACTORY
feature {NONE} -- Initialization feature {NONE} -- Initialization
make (a_request_settings: HTTPD_REQUEST_SETTINGS) make (a_request_settings: HTTPD_REQUEST_SETTINGS)
@@ -18,18 +20,20 @@ feature {NONE} -- Initialization
reset reset
-- Import global request settings. -- Import global request settings.
timeout := a_request_settings.timeout -- seconds timeout := a_request_settings.timeout -- seconds
socket_recv_timeout := a_request_settings.socket_recv_timeout -- seconds
keep_alive_timeout := a_request_settings.keep_alive_timeout -- seconds keep_alive_timeout := a_request_settings.keep_alive_timeout -- seconds
max_keep_alive_requests := a_request_settings.max_keep_alive_requests max_keep_alive_requests := a_request_settings.max_keep_alive_requests
is_verbose := a_request_settings.is_verbose is_verbose := a_request_settings.is_verbose
verbose_level := a_request_settings.verbose_level verbose_level := a_request_settings.verbose_level
is_secure := a_request_settings.is_secure
end end
reset reset
do do
reset_request reset_request
has_error := False reset_error
if attached internal_client_socket as l_sock then if attached internal_client_socket as l_sock then
l_sock.cleanup l_sock.cleanup
end end
@@ -68,7 +72,7 @@ feature -- Access
do do
s := internal_client_socket s := internal_client_socket
if s = Void then if s = Void then
create s.make_empty s := new_client_socket (is_secure)
internal_client_socket := s internal_client_socket := s
end end
Result := s Result := s
@@ -121,6 +125,10 @@ feature -- Settings
verbose_level: INTEGER verbose_level: INTEGER
-- Output verbosity. -- Output verbosity.
is_secure: BOOLEAN
-- Is secure socket?
-- i.e: SSL?
is_persistent_connection_supported: BOOLEAN is_persistent_connection_supported: BOOLEAN
-- Is persistent connection supported? -- Is persistent connection supported?
do do
@@ -134,6 +142,9 @@ feature -- Settings
timeout: INTEGER -- seconds timeout: INTEGER -- seconds
-- Amount of seconds that the server waits for receipts and transmissions during communications. -- Amount of seconds that the server waits for receipts and transmissions during communications.
socket_recv_timeout: INTEGER -- seconds
-- Amount of seconds that the server waits for receiving data on socket during communications.
max_keep_alive_requests: INTEGER max_keep_alive_requests: INTEGER
-- Maximum number of requests allowed per persistent connection. -- Maximum number of requests allowed per persistent connection.
@@ -143,7 +154,21 @@ 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
report_error (m: detachable READABLE_STRING_GENERAL)
-- Report error occurred, with optional message `m'.
do
has_error := True
end
reset_error
-- Reset previous error for current request handler.
do
has_error := False
end
feature -- Change feature -- Change
@@ -183,10 +208,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
-- 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
@@ -206,23 +242,34 @@ feature -- Execution
log ("Reuse connection (" + n.out + ")", information_level) log ("Reuse connection (" + n.out + ")", information_level)
end end
-- FIXME: it seems to be called one more time, mostly to see this is done. -- FIXME: it seems to be called one more time, mostly to see this is done.
execute_request execute_request (n > 1)
l_exit := not is_persistent_connection_supported l_exit := not is_persistent_connection_supported
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
end end
if l_exit and has_error and not l_socket.is_closed then
l_socket.close
end
end end
execute_request execute_request (a_is_reusing_connection: BOOLEAN)
-- Execute http request, and if `a_is_reusing_connection' is True
-- the execution is reusing the persistent connection.
require require
is_connected: is_connected is_connected: is_connected
reuse_connection_when_possible: a_is_reusing_connection implies is_persistent_connection_supported
no_error: not has_error
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")
if a_is_reusing_connection then
dbglog ("execute_request: wait on persistent connection.")
end
end
reset_error
l_socket := client_socket l_socket := client_socket
check check
socket_attached: l_socket /= Void socket_attached: l_socket /= Void
@@ -230,51 +277,41 @@ feature -- Execution
end end
if l_socket.is_closed then if l_socket.is_closed then
debug ("dbglog") debug ("dbglog")
dbglog (generator + ".execute_request {socket is Closed!}") dbglog ("execute_request {socket is Closed!}")
end end
else else
debug ("dbglog") debug ("dbglog")
dbglog (generator + ".execute_request socket=" + l_socket.descriptor.out + " ENTER") dbglog ("execute_request socket=" + l_socket.descriptor.out + " ENTER")
end end
--| TODO: add configuration options for socket timeout. -- Try to get request header.
--| set by default 5 seconds. -- If the request is reusing persistent connection, use `keep_alive_timeout',
l_socket.set_timeout (keep_alive_timeout) -- 5 seconds! -- otherwise `socket_recv_timeout'.
l_is_ready := l_socket.ready_for_reading get_request_header (l_socket, a_is_reusing_connection)
if l_is_ready then if has_error then
l_socket.set_timeout (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)
else
has_error := True
debug ("dbglog")
dbglog (generator + ".execute_request socket=" + l_socket.descriptor.out + "} timeout!")
end
end
if has_error then
if l_is_ready 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)
end end
is_persistent_connection_requested := False
else else
if is_verbose then if is_verbose then
log (request_header, information_level) log (request_header, information_level)
end end
process_request (l_socket) process_request (l_socket)
end end
debug ("dbglog")
dbglog (generator + ".execute_request {" + l_socket.descriptor.out + "} LEAVE") debug ("dbglog")
end dbglog ("execute_request {" + l_socket.descriptor.out + "} LEAVE")
end
end end
end end
@@ -286,7 +323,7 @@ feature -- Execution
feature -- Request processing feature -- Request processing
process_request (a_socket: HTTPD_STREAM_SOCKET) process_request (a_socket: HTTPD_STREAM_SOCKET)
-- Process request ... -- Process request on socket `a_socket'.
require require
no_error: not has_error no_error: not has_error
a_uri_attached: uri /= Void a_uri_attached: uri /= Void
@@ -297,10 +334,46 @@ feature -- Request processing
deferred deferred
end end
process_bad_request (a_socket: HTTPD_STREAM_SOCKET)
-- Process bad request catched on `a_socket'.
require
has_error: has_error
a_socket_attached: a_socket /= Void
local
-- h: STRING
-- s: STRING
do
-- NOTE: this is experiment code, and not ready yet.
-- if a_socket.ready_for_writing then
-- s := "{
--<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
--<html><head>
--<title>400 Bad Request</title>
--</head><body>
--<h1>Bad Request</h1>
--</body></html>
-- }"
-- create h.make (1_024)
-- h.append ("HTTP/1.1 400 Bad Request%R%N")
-- h.append ("Content-Length: " + s.count.out + "%R%N")
-- h.append ("Connection: close%R%N")
-- h.append ("Content-Type: text/html; charset=iso-8859-1%R%N")
-- h.append ("%R%N")
-- a_socket.put_string (h)
-- if a_socket.ready_for_writing then
-- a_socket.put_string (s)
-- end
-- end
end
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
@@ -313,72 +386,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.is_readable and then a_socket.readable
attached next_line (a_socket) as l_request_line and then
not l_request_line.is_empty
then then
txt.append (l_request_line) if a_is_reusing_connection then
txt.append_character ('%N') a_socket.set_recv_timeout (keep_alive_timeout) -- in seconds!
analyze_request_line (l_request_line)
else
has_error := True
end
l_is_verbose := is_verbose
if not has_error or l_is_verbose then
-- if `is_verbose' we can try to print the request, even if it is a bad HTTP request
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 else
-- By default HTTP:1/1 support persistent connection. a_socket.set_recv_timeout (socket_recv_timeout) -- FIXME: return a 408 Request Timeout response ..
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
if
attached next_line (a_socket) as l_request_line and then
not l_request_line.is_empty and then
not has_error
then
txt.append (l_request_line)
txt.append_character ('%N')
analyze_request_line (l_request_line)
if not has_error then
if a_is_reusing_connection then
-- Restore normal recv timeout!
a_socket.set_recv_timeout (socket_recv_timeout) -- FIXME: return a 408 Request Timeout response ..
end
from
line := next_line (a_socket)
until
line = Void or end_of_stream or has_error
loop
n := line.count
debug ("ew_standalone")
if l_is_verbose then
log (line, debug_level)
end
end
pos := line.index_of (':', 1)
if pos > 0 then
k := line.substring (1, pos - 1)
if line [pos + 1].is_space then
pos := pos + 1
end
if line [n] = '%R' then
n := n - 1
end
val := line.substring (pos + 1, n)
request_header_map.put (val, k)
end
txt.append (line)
txt.append_character ('%N')
if line.is_empty or else line [1] = '%R' then
end_of_stream := True
else
line := next_line (a_socket)
end
end
-- Except for HTTP/1.0, persistent connection is the default.
is_persistent_connection_requested := True
if is_http_version_1_0 then
is_persistent_connection_requested := attached request_header_map.item ("Connection") as l_connection and then
l_connection.is_case_insensitive_equal_general ("keep-alive")
else
-- By default HTTP:1/1 support persistent connection.
if attached request_header_map.item ("Connection") as l_connection then
if l_connection.is_case_insensitive_equal_general ("close") then
is_persistent_connection_requested := False
end
else
is_persistent_connection_requested := True
end
end
end
else
report_error ("Bad header line (empty)")
end
else
report_error ("Socket is not readable")
end 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
@@ -399,39 +490,44 @@ feature -- Parsing
n := n - 1 n := n - 1
end end
version := line.substring (next_pos + 1, n) version := line.substring (next_pos + 1, n)
has_error := method.is_empty if method.is_empty then
report_error ("Missing request method data")
end
end end
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
has_error := True report_error ("Rescue in next_line")
a_socket.close
Result := Void Result := Void
elseif a_socket.readable then elseif a_socket.readable then
a_socket.read_line_thread_aware a_socket.read_line_noexception
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
has_error := True 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
-- Error with socket... -- Error with socket...
has_error := True report_error ("Socket error: not readable")
if is_verbose then if is_verbose then
log (request_header + "%N## Socket is not readable! ##", debug_level) log (request_header + "%N## Socket is not readable! ##", debug_level)
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
@@ -462,6 +558,19 @@ feature -- Output
end end
end end
feature {NONE} -- Helpers
socket_has_incoming_data (a_socket: HTTPD_STREAM_SOCKET): BOOLEAN
-- Is there any data to read on `a_socket' ?
require
a_socket.readable
do
-- FIXME: check if both are really needed.
-- Result := a_socket.ready_for_reading --and then a_socket.has_incoming_data
-- Result := a_socket.has_incoming_data
Result := True
end
invariant invariant
request_header_attached: request_header /= Void request_header_attached: request_header /= Void

View File

@@ -108,8 +108,18 @@ feature -- Execution
log (" - max_tcp_clients = " + configuration.max_tcp_clients.out) log (" - max_tcp_clients = " + configuration.max_tcp_clients.out)
log (" - max_concurrent_connections = " + configuration.max_concurrent_connections.out) log (" - max_concurrent_connections = " + configuration.max_concurrent_connections.out)
log (" - socket_timeout = " + configuration.socket_timeout.out + " seconds") log (" - socket_timeout = " + configuration.socket_timeout.out + " seconds")
log (" - socket_recv_timeout = " + configuration.socket_recv_timeout.out + " seconds")
log (" - keep_alive_timeout = " + configuration.keep_alive_timeout.out + " seconds") log (" - keep_alive_timeout = " + configuration.keep_alive_timeout.out + " seconds")
log (" - max_keep_alive_requests = " + configuration.max_keep_alive_requests.out) log (" - max_keep_alive_requests = " + configuration.max_keep_alive_requests.out)
if configuration.has_ssl_support then
if configuration.is_secure then
log (" - SSL = enabled")
else
log (" - SSL = disabled")
end
else
log (" - SSL = not supported")
end
if configuration.verbose_level > 0 then if configuration.verbose_level > 0 then
log (" - verbose_level = " + configuration.verbose_level.out) log (" - verbose_level = " + configuration.verbose_level.out)
end end

View File

@@ -1,334 +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)"
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
read_into_pointer_noexception (p: POINTER; start_pos, nb_bytes: INTEGER_32)
-- Read at most `nb_bytes' bound bytes and make result
-- available in `p' at position `start_pos'.
-- No exception raised!
require
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 {NETWORK_STREAM_SOCKET} socket as l_socket then from
l_socket.set_connect_timeout (n) 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
set_accept_timeout (n: INTEGER) bytes_read_updated: 0 <= bytes_read and bytes_read <= nb_bytes
do
if attached {NETWORK_STREAM_SOCKET} socket as l_socket then
l_socket.set_accept_timeout (n)
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
bytes_read: INTEGER
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
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 do
socket.put_string (s) peek_stream_noexception (1)
Result := last_string.count = 1
end end
put_character (c: CHARACTER) note
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
ready_for_reading: BOOLEAN
do
if attached {TCP_STREAM_SOCKET} socket as l_socket then
Result := l_socket.ready_for_reading
end
end
try_ready_for_reading: BOOLEAN
do
if attached {TCP_STREAM_SOCKET} socket as l_socket then
Result := l_socket.try_ready_for_reading
end
end
accepted: detachable HTTPD_STREAM_SOCKET
do
if attached {NETWORK_STREAM_SOCKET} socket.accepted as l_accepted then
create Result.make (l_accepted)
end
end
feature {HTTPD_STREAM_SOCKET} -- Implementation
make (a_socket: STREAM_SOCKET)
do
socket := a_socket
end
socket: STREAM_SOCKET
network_stream_socket: detachable NETWORK_STREAM_SOCKET
do
if attached {NETWORK_STREAM_SOCKET} socket as s then
Result := s
end
end
;note
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: "[
@@ -338,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,151 +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
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
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: STRING; a_key: STRING) 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, a_key) 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: STRING; a_key: STRING) 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, a_key)
end
make_ssl_client_by_address_and_port (an_address: INET_ADDRESS; a_port: INTEGER; a_ssl_protocol: NATURAL; a_crt: STRING; a_key: STRING) 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, a_key) 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: STRING; a_key: STRING) 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, a_key) end
bytes_read := l_read
else
check has_context: False end
end
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'.
do -- No exception raised!
if attached {SSL_TCP_STREAM_SOCKET} socket as l_ssl_socket then
Result := l_ssl_socket.port
else
Result := Precursor
end
end
is_bound: BOOLEAN
-- <Precursor>
do
if attached {SSL_TCP_STREAM_SOCKET} socket as l_ssl_socket then
Result := l_ssl_socket.is_bound
else
Result := Precursor
end
end
ready_for_writing: BOOLEAN
-- <Precursor>
do
if attached {SSL_TCP_STREAM_SOCKET} socket as l_ssl_socket then
Result := l_ssl_socket.ready_for_writing
else
Result := Precursor
end
end
ready_for_reading: BOOLEAN
-- <Precursor>
do
if attached {SSL_TCP_STREAM_SOCKET} socket as l_ssl_socket then
Result := l_ssl_socket.ready_for_reading
else
Result := Precursor
end
end
try_ready_for_reading: BOOLEAN
do
if attached {SSL_TCP_STREAM_SOCKET} socket as l_socket then
Result := l_socket.try_ready_for_reading
else
Result := Precursor
end
end
feature {HTTPD_STREAM_SOCKET} -- Implementation
set_certificates (a_crt: STRING; a_key: STRING)
local local
a_file_name: FILE_NAME l_bytes_sent: INTEGER
do do
if attached {SSL_NETWORK_STREAM_SOCKET} socket as l_socket then if
create a_file_name.make_from_string (a_crt) attached context as l_context and then
l_socket.set_certificate_file_name (a_file_name) attached l_context.last_ssl as l_ssl
create a_file_name.make_from_string (a_key) then
l_socket.set_key_file_name (a_file_name) l_bytes_sent := ssl_write (l_ssl, a_pointer + a_offset, a_byte_count)
if l_bytes_sent < a_byte_count then
socket_error := "No all bytes sent!"
end
bytes_sent := l_bytes_sent
else
check has_last_ssl: False end
end
end
feature -- Element change
set_certificate_filenames (a_crt_filename, a_key_filename: detachable READABLE_STRING_GENERAL)
do
if a_crt_filename /= Void then
set_certificate_file_name (a_crt_filename)
end
if a_key_filename /= Void then
set_key_file_name (a_key_filename)
end end
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,96 +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
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
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
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

@@ -0,0 +1,17 @@
note
description: "Summary description for {HTTPD_SOCKET_FACTORY}."
date: "$Date$"
revision: "$Revision$"
deferred class
HTTPD_SOCKET_FACTORY
feature -- Access
new_client_socket (a_is_secure: BOOLEAN): HTTPD_STREAM_SOCKET
do
check not_secure: not a_is_secure end
create Result.make_empty
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

@@ -0,0 +1,20 @@
note
description: "Summary description for {HTTPD_SOCKET_FACTORY}."
date: "$Date$"
revision: "$Revision$"
deferred class
HTTPD_SOCKET_FACTORY
feature -- Access
new_client_socket (a_is_secure: BOOLEAN): HTTPD_STREAM_SOCKET
do
if a_is_secure then
create {HTTPD_STREAM_SSL_SOCKET} Result.make_empty
else
create Result.make_empty
end
end
end

View File

@@ -97,7 +97,9 @@ feature -- Request processing
end end
end end
rescue rescue
has_error := l_output = Void or else not l_output.is_available if l_output = Void or else not l_output.is_available then
report_error ("Missing WGI output")
end
if not retried then if not retried then
retried := True retried := True
retry retry
@@ -230,6 +232,9 @@ feature -- Request processing
set_environment_variable (l_server_port, "SERVER_PORT", Result) set_environment_variable (l_server_port, "SERVER_PORT", Result)
set_environment_variable (version, "SERVER_PROTOCOL", Result) set_environment_variable (version, "SERVER_PROTOCOL", Result)
set_environment_variable ({HTTPD_CONFIGURATION}.Server_details, "SERVER_SOFTWARE", Result) set_environment_variable ({HTTPD_CONFIGURATION}.Server_details, "SERVER_SOFTWARE", Result)
if is_secure then
set_environment_variable ("on", "HTTPS", Result)
end
--| Apply `base' value --| Apply `base' value
l_base := base l_base := base

View File

@@ -2,8 +2,8 @@ note
description: "[ description: "[
Standalone Web Server connector. Standalone Web Server connector.
]" ]"
date: "$Date$" date: "$Date: 2016-08-06 13:34:52 +0200 (sam., 06 août 2016) $"
revision: "$Revision$" revision: "$Revision: 99106 $"
class class
WGI_STANDALONE_CONNECTOR [G -> WGI_EXECUTION create make end] WGI_STANDALONE_CONNECTOR [G -> WGI_EXECUTION create make end]
@@ -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
@@ -155,9 +172,22 @@ feature -- Element change
set_is_verbose_on_configuration (b, configuration) set_is_verbose_on_configuration (b, configuration)
end end
set_is_secure (b: BOOLEAN)
-- Set is_secure connection mode.
-- i.e: using SSL.
do
set_is_secure_on_configuration (b, configuration)
end
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
@@ -183,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
@@ -232,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)
@@ -242,6 +277,11 @@ feature {NONE} -- Implementation: element change
cfg.set_is_verbose (b) cfg.set_is_verbose (b)
end end
set_is_secure_on_configuration (b: BOOLEAN; cfg: like configuration)
do
cfg.set_is_secure (b)
end
note note
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"

View File

@@ -0,0 +1,18 @@
note
description: "[
Constants value related to Standalone connector,
and indirectly to `httpd' component.
]"
author: "$Author$"
date: "$Date$"
revision: "$Revision$"
deferred class
WGI_STANDALONE_CONSTANTS
inherit
ANY
HTTPD_CONSTANTS
end

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

@@ -26,4 +26,10 @@
</target> </target>
<target name="test_connector_standalone" extends="test_standalone_scoop"> <target name="test_connector_standalone" extends="test_standalone_scoop">
</target> </target>
<target name="test_standalone_scoop_ssl" extends="test_standalone_scoop">
<variable name="httpd_ssl_enabled" value="true"/>
<variable name="libcurl_http_client_disabled" value="true"/>
<variable name="net_http_client_disabled" value="false"/>
<variable name="netssl_http_client_enabled" value="true"/>
</target>
</system> </system>

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

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

@@ -2,14 +2,27 @@ note
description: "[ description: "[
Component to launch the service using the default connector Component to launch the service using the default connector
Eiffel Web httpd for this class EiffelWeb httpd for this class
The httpd default connector support options:
verbose: to display verbose output
port: numeric such as 8099 (or equivalent string as "8099")
base: base_url (very specific to standalone server)
max_concurrent_connections: set one, for single threaded behavior
max_tcp_clients: max number of open tcp connection
socket_timeout: connection timeout
socket_recv_timeout: read data timeout
keep_alive_timeout: amount of time the server will wait for subsequent
requests on a persistent connection,
max_keep_alive_requests: number of requests allowed on a persistent connection,
ssl_enabled: set to True for https support.
ssl_ca_crt: path to the certificat crt file (relevant when ssl_enabled is True)
ssl_ca_key: path to the certificat key file (relevant when ssl_enabled is True)
The httpd default connector support options:
port: numeric such as 8099 (or equivalent string as "8099")
base: base_url (very specific to standalone server)
verbose: to display verbose output, useful for standalone connector
force_single_threaded: use only one thread, useful for standalone connector
check WSF_SERVICE_LAUNCHER for more documentation check WSF_SERVICE_LAUNCHER for more documentation
]" ]"
@@ -41,16 +54,17 @@ feature {NONE} -- Initialization
create on_launched_actions create on_launched_actions
create on_stopped_actions create on_stopped_actions
port_number := 80 --| Default, but quite often, this port is already used ... port_number := {WGI_STANDALONE_CONSTANTS}.default_http_server_port --| Default, but quite often, this port is already used ...
max_concurrent_connections := 100 max_concurrent_connections := {WGI_STANDALONE_CONSTANTS}.default_max_concurrent_connections
max_tcp_clients := 100 max_tcp_clients := {WGI_STANDALONE_CONSTANTS}.default_max_tcp_clients
socket_timeout := 300 -- 300 seconds socket_timeout := {WGI_STANDALONE_CONSTANTS}.default_socket_timeout -- seconds
keep_alive_timeout := 15 -- 15 seconds. socket_recv_timeout := {WGI_STANDALONE_CONSTANTS}.default_socket_recv_timeout -- seconds
max_keep_alive_requests := 100 keep_alive_timeout := {WGI_STANDALONE_CONSTANTS}.default_keep_alive_timeout -- seconds.
max_keep_alive_requests := {WGI_STANDALONE_CONSTANTS}.default_max_keep_alive_requests
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
@@ -59,6 +73,7 @@ feature {NONE} -- Initialization
if attached {READABLE_STRING_GENERAL} opts.option ("base") as l_base_str then if attached {READABLE_STRING_GENERAL} opts.option ("base") as l_base_str then
base_url := l_base_str.as_string_8 base_url := l_base_str.as_string_8
end end
verbose := opts.option_boolean_value ("verbose", verbose) verbose := opts.option_boolean_value ("verbose", verbose)
-- See `{HTTPD_REQUEST_HANDLER_I}.*_verbose_level` -- See `{HTTPD_REQUEST_HANDLER_I}.*_verbose_level`
@@ -96,8 +111,16 @@ feature {NONE} -- Initialization
max_concurrent_connections := opts.option_integer_value ("max_concurrent_connections", max_concurrent_connections) max_concurrent_connections := opts.option_integer_value ("max_concurrent_connections", max_concurrent_connections)
max_tcp_clients := opts.option_integer_value ("max_tcp_clients", max_tcp_clients) max_tcp_clients := opts.option_integer_value ("max_tcp_clients", max_tcp_clients)
socket_timeout := opts.option_integer_value ("socket_timeout", socket_timeout) socket_timeout := opts.option_integer_value ("socket_timeout", socket_timeout)
socket_recv_timeout := opts.option_integer_value ("socket_recv_timeout", socket_recv_timeout)
keep_alive_timeout := opts.option_integer_value ("keep_alive_timeout", keep_alive_timeout) keep_alive_timeout := opts.option_integer_value ("keep_alive_timeout", keep_alive_timeout)
max_keep_alive_requests := opts.option_integer_value ("max_keep_alive_requests", max_keep_alive_requests) max_keep_alive_requests := opts.option_integer_value ("max_keep_alive_requests", max_keep_alive_requests)
if
opts.option_boolean_value ("ssl_enabled", ssl_enabled) and then
attached opts.option_string_32_value ("ssl_protocol", "tls_1_2") as ssl_prot
then
ssl_settings := [ssl_prot, opts.option_string_32_value ("ssl_ca_crt", Void), opts.option_string_32_value ("ssl_ca_key", Void)]
end
end end
create conn.make create conn.make
@@ -120,11 +143,13 @@ feature -- Execution
do do
cfg.set_is_verbose (verbose) cfg.set_is_verbose (verbose)
cfg.set_verbose_level (verbose_level) cfg.set_verbose_level (verbose_level)
cfg.set_ssl_settings (ssl_settings)
cfg.set_http_server_name (server_name) cfg.set_http_server_name (server_name)
cfg.http_server_port := port_number cfg.http_server_port := port_number
cfg.set_max_concurrent_connections (max_concurrent_connections) cfg.set_max_concurrent_connections (max_concurrent_connections)
cfg.set_max_tcp_clients (max_tcp_clients) cfg.set_max_tcp_clients (max_tcp_clients)
cfg.set_socket_timeout (socket_timeout) cfg.set_socket_timeout (socket_timeout)
cfg.set_socket_recv_timeout (socket_recv_timeout)
cfg.set_keep_alive_timeout (keep_alive_timeout) cfg.set_keep_alive_timeout (keep_alive_timeout)
cfg.set_max_keep_alive_requests (max_keep_alive_requests) cfg.set_max_keep_alive_requests (max_keep_alive_requests)
end end
@@ -140,10 +165,21 @@ feature -- Execution
debug ("ew_standalone") debug ("ew_standalone")
if verbose then if verbose then
io.error.put_string ("Launching standalone web server on port " + port_number.out) io.error.put_string ("Launching standalone web server on port " + port_number.out)
if attached server_name as l_name then if ssl_enabled then
io.error.put_string ("%N http://" + l_name + ":" + port_number.out + "/" + base_url + "%N") io.error.put_string ("%N https://")
else else
io.error.put_string ("%N http://localhost:" + port_number.out + "/" + base_url + "%N") io.error.put_string ("%N http://")
end
if attached server_name as l_name then
io.error.put_string (l_name)
else
io.error.put_string ("localhost")
end
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 end
@@ -170,16 +206,25 @@ 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
-- Help defining the verbosity. -- Help defining the verbosity.
-- The higher, the more output. -- The higher, the more output.
ssl_settings: detachable TUPLE [protocol: READABLE_STRING_GENERAL; ca_crt, ca_key: detachable READABLE_STRING_GENERAL]
ssl_enabled: BOOLEAN
-- Is secure server? i.e using SSL?
do
Result := attached ssl_settings as ssl and then attached ssl.protocol as prot and then not prot.is_whitespace
end
max_concurrent_connections: INTEGER max_concurrent_connections: INTEGER
max_tcp_clients: INTEGER max_tcp_clients: INTEGER
socket_timeout: INTEGER socket_timeout: INTEGER
socket_recv_timeout: INTEGER
keep_alive_timeout: INTEGER keep_alive_timeout: INTEGER
max_keep_alive_requests: INTEGER max_keep_alive_requests: INTEGER

View File

@@ -22,11 +22,11 @@ note
For instance, you can use For instance, you can use
create s.make_and_launch_and_options (agent execute, <<["port", 8099]>>) create s.make_and_launch_and_options (agent execute, <<["port", 8099]>>)
And if Nino is the default connector it will support: And if the connector is the Standalone connector,
check {WSF_STANDALONE_SERVICE_LAUNCHER} for options description, such as:
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.
verbose: to display verbose output, useful for Nino
]" ]"
date: "$Date$" date: "$Date$"
revision: "$Revision$" revision: "$Revision$"

View File

@@ -2,14 +2,13 @@ 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$" date: "$Date: 2016-08-06 13:34:52 +0200 (sam., 06 août 2016) $"
revision: "$Revision$" revision: "$Revision: 99106 $"
class class
WSF_SERVICE_LAUNCHER_OPTIONS WSF_SERVICE_LAUNCHER_OPTIONS
@@ -85,6 +84,12 @@ feature -- Access
feature -- Helpers feature -- Helpers
has_option (a_opt_name: READABLE_STRING_GENERAL): BOOLEAN
-- Is there any value associated to option name `a_opt_name'?
do
Result := attached option (a_opt_name)
end
has_integer_option (a_opt_name: READABLE_STRING_GENERAL): BOOLEAN has_integer_option (a_opt_name: READABLE_STRING_GENERAL): BOOLEAN
-- Is there any INTEGER value associated to option name `a_opt_name'? -- Is there any INTEGER value associated to option name `a_opt_name'?
local local
@@ -100,6 +105,29 @@ feature -- Helpers
end end
end end
has_string_32_option (a_opt_name: READABLE_STRING_GENERAL): BOOLEAN
-- Is there any string 32 value associated to option name `a_opt_name'?
do
if attached option (a_opt_name) as opt then
Result := attached {READABLE_STRING_GENERAL} opt
end
end
option_string_32_value (a_opt_name: READABLE_STRING_GENERAL; a_default: detachable READABLE_STRING_GENERAL): detachable IMMUTABLE_STRING_32
-- Unicode String value associated to option name `a_opt_name', other return `a_default'.
do
if attached option (a_opt_name) as opt then
if attached {READABLE_STRING_32} opt as s32 then
create Result.make_from_string (s32)
elseif attached {READABLE_STRING_GENERAL} opt as s then
create Result.make_from_string_general (s)
end
end
if Result = Void and a_default /= Void then
create Result.make_from_string_general (a_default)
end
end
option_integer_value (a_opt_name: READABLE_STRING_GENERAL; a_default: INTEGER): INTEGER option_integer_value (a_opt_name: READABLE_STRING_GENERAL; a_default: INTEGER): INTEGER
-- INTEGER value associated to option name `a_opt_name', other return `a_default'. -- INTEGER value associated to option name `a_opt_name', other return `a_default'.
local local

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

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