Compare commits

...

35 Commits

Author SHA1 Message Date
Jocelyn Fiat
a0c1ab5232 updated simple.ini settings. 2017-10-19 11:20:14 +02:00
Jocelyn Fiat
db39068ceb Updated documentation for standalone connector.
Changed `default_max_keep_alive_requests` from 100 to 300.
2017-10-19 00:14:23 +02:00
Jocelyn Fiat
a1b4337438 Set keep_alive_timeout to 2, this way for single threaded case, browser does not wait too much to start the websocket connection.
Set max_keep_alive_requests to -1, to allow unlimited number of requests within a same websocket connection.
2017-10-18 23:41:03 +02:00
Jocelyn Fiat
74121be470 Support persistent connection, even in single thread mode (i.e concurrency=none).
Warning: as there is no concurrent request handling in single threaded mode,
            it is recommended to either set the keep_alive_timeout to a small value,
            or disable persistent connection by setting max_keep_alive_requests to 0.
Change the default keep_alive_timeout from 15 to 5 seconds.
Accept -1 as value of max_keep_alive_requests to have unlimited number of request in the same persistent connection.
2017-10-18 23:29:16 +02:00
Jocelyn Fiat
edec837c4e Made interface of wsf forms and widgets a bit more flexible by accepting READABLE_STRING_GENERAL. 2017-10-17 14:34:50 +02:00
Jocelyn Fiat
f1642a444a Improved support of absolute/relative https:// and http:// in http_client. 2017-10-17 14:30:44 +02:00
Jocelyn Fiat
48af63af83 Fixed typo to process relative or absolute url. 2017-10-09 14:23:45 +02:00
Jocelyn Fiat
2f98d7031f Updated a few package.iron files. 2017-10-06 14:06:46 +02:00
Jocelyn Fiat
70f00651c7 update test case. 2017-10-06 13:58:54 +02:00
Jocelyn Fiat
199f84c7ef Updated Readme file with Build Status on Master Branch. 2017-10-06 10:37:11 +02:00
Jocelyn Fiat
9b97627c76 Update package.iron files. 2017-10-06 10:27:32 +02:00
Jocelyn Fiat
72c87cd74d Fixed curl implementation by setting Content-Type to x-www-form-urlencoded (if not set) when POST send data as x-www-form-urlencoded. 2017-10-06 10:24:48 +02:00
Jocelyn Fiat
2ed4d03168 Renamed ciphers_settings as ciphers_setting . 2017-10-06 09:34:08 +02:00
Jocelyn Fiat
18ed92a61d Moved to unique .ecf from ecf version 1-16-0 .
Requires 17.05 or newer.
2017-10-06 09:02:10 +02:00
Jocelyn Fiat
0a6a4281e7 Merge branch 'master' into es17.05 2017-10-06 08:18:50 +02:00
Jocelyn Fiat
38cf5d7a6f Updated requirements, now EiffelWeb requires 17.05 or newer.
Improved support for future 17.11 version with new openssl library.
2017-10-05 22:07:05 +02:00
jvelilla
96648a16dc Updated Readme file with Build Status on Master Branch.
Update code style: refactor rename ciphers_settings to ciphers_setting.
2017-09-25 14:21:35 -03:00
Javier Velilla
6f35ad7b16 Merge pull request #181 from jvelilla/ewf_http_client
Update HTTP Client cURL implementation:
2017-09-25 11:05:45 -03:00
jvelilla
85c8a46c89 Update Readme.md with a note about ciphers implementation. 2017-09-21 08:07:11 -03:00
Jocelyn Fiat
498e4a6ec2 Fixed validation of iss and aud when issuer and audience are not set. 2017-09-21 10:46:08 +02:00
Jocelyn Fiat
ab507d543a Now HTTP_AUTHORIZATION acceps READABLE_STRING_GENERAL for username and password argument. 2017-09-21 10:45:40 +02:00
Jocelyn Fiat
20a90db2e3 If url is relative, use session.url (...) to get valid url.
It could happen with relative url in `Location: ...` header (for redirection).
2017-09-21 10:45:08 +02:00
jvelilla
6ed91699b8 Renamed feature 'set_ciphers' to 'set_ciphers_settings' and added description. 2017-09-19 10:32:17 -03:00
jvelilla
bb334aef80 Updated HTTP client cURL implementation.
Refactor rename cipher_list by ciphers_settings and description.
Updated ciphers_settings representation to STIRNG_8
Refactor rename set_cipher_list by set_ciphers.
2017-09-14 11:58:43 -03:00
jvelilla
c2764e25ff Update HTTP Client cURL implementation:
Added the option to set cipher list used to negotiate security settings
(SSL handshake)
2017-09-14 10:21:32 -03:00
Jocelyn Fiat
6425482070 Fixed ecf by removing the override declaration. 2017-08-08 15:55:52 +02:00
Jocelyn Fiat
818c3fb460 Made compilable with EiffelStudio 17.05 and probably before as well. 2017-08-08 15:54:21 +02:00
Jocelyn Fiat
dac50b490d Added output for the travis CI job. 2017-08-08 14:10:12 +02:00
Jocelyn Fiat
16d5076fe5 Added Travis CI support with 17.05. 2017-08-08 14:03:39 +02:00
Jocelyn Fiat
2748e1d9ee Now JWT_LOADER takes the alg as argument, to avoid security issue where the lib is taking alg from the header (which may be a bad security weakness). 2017-07-11 23:32:11 +02:00
Jocelyn Fiat
27ee20f99b Added convenient get and custom functions on HTTP_CLIENT directly. 2017-07-11 23:29:42 +02:00
Javier Velilla
9a3164df70 Merge pull request #178 from jvelilla/ewf_ssl
Updated EWF  http_network, websocket, httpd to use the latest EiffelN…
2017-06-23 09:53:26 -03:00
jvelilla
02383810b4 Fixed bad identation
Updated date to current date in obsolte message.
2017-06-23 09:51:59 -03:00
jvelilla
dbf5e76047 Updated EWF network and httpd libraries.
Updated features using ssl_2 and ssl_3 as obsolete and raise a
developer exception.
2017-06-22 10:23:56 -03:00
jvelilla
5c31905427 Updated EWF http_network, websocket, httpd to use the latest EiffelNet SSL
version.
2017-06-21 18:34:07 -03:00
67 changed files with 794 additions and 666 deletions

View File

@@ -0,0 +1,19 @@
language: eiffel
before_script:
- export current_dir=$PWD ; echo current_dir=$current_dir ; cd ..
- export ISE_VERSION=17.05; export ISE_BUILD=100416
- curl -sSL http://downloads.sourceforge.net/eiffelstudio/Eiffel_${ISE_VERSION}_gpl_${ISE_BUILD}-linux-x86-64.tar.bz2 | tar -x --bzip2
- export ISE_EIFFEL=$PWD/Eiffel_${ISE_VERSION} ; export ISE_PLATFORM=linux-x86-64
- export PATH=$PATH:$ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin:$PATH:$ISE_EIFFEL/tools/spec/$ISE_PLATFORM/bin
- echo `ec -version`
- cd $current_dir
- echo Check projects compilation status...
branches:
only:
- master
- v1
script: compile_all -ecb -melt -list_failures -log_verbose -clean -options dotnet=false
group: stable
os: linux

View File

@@ -7,14 +7,21 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
## [Unreleased] ## [Unreleased]
### Added ### Added
- jwt: new JSON Web Token (JWT) library (supports for claim exp, iat, nbf, iss, aud). - `jwt`: new JSON Web Token (JWT) library (supports for claim exp, iat, nbf, iss, aud).
- `http_client`: added support for ciphers setting in the libcurl implementation only.
- `http_client`: added convenient `get` and `custom` functions on HTTP_CLIENT directly.
### Changed ### Changed
- adopted ecf version 1-16-0 and use a single .ecf file (the -safe.ecf are now redirection to normal .ecf)
### Deprecated ### Deprecated
- removed support for Eiffel version before 17.05 .
- SSL 2 or 3 is obsolete and will raise an exception if used.
### Removed ### Removed
### Fixed ### Fixed
- Removed a few obsolete calls. - Removed a few obsolete calls.
- `http_client`: Added support for multiple file in form data. Made clear what is the meaning of `upload_filename`, `upload_data` and `form_data`. - `http_client`: Added support for multiple file in form data. Made clear what is the meaning of `upload_filename`, `upload_data` and `form_data`.
- `authentication`: HTTP_AUTHORIZATION acceps now READABLE_STRING_GENERAL for username and password argument.
- `http_client`: fixed curl implementation by setting `Content-Type` to `x-www-form-urlencoded` (if not set) when POST send data as `x-www-form-urlencoded`.
### Security ### Security

View File

@@ -1,5 +1,7 @@
# Eiffel Web Framework # Eiffel Web Framework
[![Build Status](https://api.travis-ci.org/EiffelWebFramework/EWF.svg?branch=master)](https://travis-ci.org/EiffelWebFramework/EWF/)
## Overview ## Overview

View File

@@ -1,7 +1,6 @@
package nino package nino
project project
nino = "nino-safe.ecf"
nino = "nino.ecf" nino = "nino.ecf"
note note

View File

@@ -59,7 +59,7 @@ feature -- Basic operations
end end
``` ```
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. When using the [standalone](../connectors/standalone.md) 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).
@@ -86,6 +86,8 @@ feature {NONE} -- Initialization
end end
``` ```
Learn more about the [Standalone](../connectors/standalone.md) connector.
The **WSF_REQUEST** gives access to the incoming data; the class provides features to get information such as request method, form data, query parameters, uploaded files, HTTP request headers, and hostname of the client among others. The **WSF_REQUEST** gives access to the incoming data; the class provides features to get information such as request method, form data, query parameters, uploaded files, HTTP request headers, and hostname of the client among others.
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.

View File

@@ -0,0 +1,27 @@
Nav: [Workbook](../workbook.md)
## The EiffelWeb standalone connector
It provides a standalone httpd server for the EiffelWeb framework.
It implements HTTP/1.1 with persistent connection, concurrent connection, ...
To easily set the standalone connector, see class `WSF_STANDALONE_SERVICE_OPTIONS`.
### Main settings:
* `port`: Listening port number (defaut: 80).
* `max_concurrent_connections`: maximum of concurrent connections (default: 100)
* `max_tcp_clients`: Listen on socket for at most `max_tcp_clients` connections (default: 100)
* `socket_timeout`: Amount of seconds the server waits for receipts and transmissions during communications. With timeout of 0, socket can wait for ever. (default: 60)
* `socket_recv_timeout`: Amount of seconds the server waits for receiving data during communications. With timeout of 0, socket can waits for ever. (default: 5)
* `keep_alive_timeout`: Persistent connection timeout. Number of seconds the server waits after a request has been served before it closes the connection (default: 5)
* `max_keep_alive_requests`: Maximum number of requests allowed per persistent connection. To disable KeepAlive, set `max_keep_alive_requests` to `0`. To have no limit, set `max_keep_alive_requests` to `-1` (default: 300).
* `is_secure`: check SSL certificate?
* `secure_certificate`: path to SSL certificate.
* `secure_certificate_key`: certificate key
* `verbose`: display verbose output (Default: false)
See also `WGI_STANDALONE_CONSTANTS` for default values.

View File

@@ -2,8 +2,8 @@ verbose=true
verbose_level=ALERT verbose_level=ALERT
port=9090 port=9090
#max_concurrent_connections=100 #max_concurrent_connections=100
keep_alive_timeout=3 #keep_alive_timeout=5
#max_tcp_clients=100
socket_timeout=60
socket_recv_timeout=15
#max_keep_alive_requests=300 #max_keep_alive_requests=300
#max_tcp_clients=100
#socket_timeout=60
#socket_recv_timeout=15

View File

@@ -3,9 +3,9 @@
<target name="websocket_app"> <target name="websocket_app">
<root class="APPLICATION" feature="make_and_launch"/> <root class="APPLICATION" feature="make_and_launch"/>
<file_rule> <file_rule>
<exclude>/\.svn$</exclude>
<exclude>/CVS$</exclude> <exclude>/CVS$</exclude>
<exclude>/EIFGENs$</exclude> <exclude>/EIFGENs$</exclude>
<exclude>/\.svn$</exclude>
</file_rule> </file_rule>
<option warning="true"> <option warning="true">
<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"/>
@@ -17,6 +17,14 @@
<library name="wsf" location="..\..\library\server\wsf\wsf.ecf"/> <library name="wsf" location="..\..\library\server\wsf\wsf.ecf"/>
<cluster name="app" location=".\" recursive="true"/> <cluster name="app" location=".\" recursive="true"/>
</target> </target>
<target name="websocket_app_st" extends="websocket_app">
<description>Single thread solution.
Warning: as it can not handle concurrent request, it is recommended to set Keep-Alive-Timeout to very low value, as browser will keep persistent connection open too long.
</description>
<capability>
<concurrency use="none"/>
</capability>
</target>
<target name="websocket_app_ssl" extends="websocket_app"> <target name="websocket_app_ssl" extends="websocket_app">
<variable name="ssl_enabled" value="true"/> <variable name="ssl_enabled" value="true"/>
</target> </target>

View File

@@ -1,13 +1,20 @@
verbose=true
verbose_level=INFORMATION
port=9090 port=9090
#Socket and timeout
max_concurrent_connections=100 max_concurrent_connections=100
keep_alive_timeout=35
max_tcp_clients=100 max_tcp_clients=100
socket_timeout=30 socket_timeout=30
socket_recv_timeout=5 socket_recv_timeout=5
max_keep_alive_requests=300
#Persistent connections
keep_alive_timeout=2
max_keep_alive_requests=-1
#SSL
is_secure=false is_secure=false
secure_certificate=ca.crt secure_certificate=ca.crt
secure_certificate_key=ca.key secure_certificate_key=ca.key
#Debug
verbose=true
verbose_level=INFORMATION

View File

@@ -10,6 +10,9 @@ It provides simple routine to perform http requests, and get response.
- Eiffel Net library - Eiffel Net library
- and optionally Eiffel NetSSL library to support `https://...` - and optionally Eiffel NetSSL library to support `https://...`
* Note: set ciphers setting is supported only with libcurl implementation for now, net implementation
set all the ciphers as part of the OpenSSL initialization.
This means on Windows, do not forget to copy the libcurl.dll (and related) either in the same directory of the executable, or ensure the .dll are in the PATH environment. This means on Windows, do not forget to copy the libcurl.dll (and related) either in the same directory of the executable, or ensure the .dll are in the PATH environment.
It is possible to exclude the libcurl implementation xor the Eiffel Net implementation: It is possible to exclude the libcurl implementation xor the Eiffel Net implementation:

View File

@@ -7,8 +7,6 @@
<exclude>/\.svn$</exclude> <exclude>/\.svn$</exclude>
<exclude>/EIFGENs$</exclude> <exclude>/EIFGENs$</exclude>
</file_rule> </file_rule>
<option warning="true">
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="curl" location="$ISE_LIBRARY\library\cURL\cURL.ecf"> <library name="curl" location="$ISE_LIBRARY\library\cURL\cURL.ecf">
<condition> <condition>
@@ -32,8 +30,8 @@
</library> </library>
<library name="uri" location="$ISE_LIBRARY\library\text\uri\uri.ecf"/> <library name="uri" location="$ISE_LIBRARY\library\text\uri\uri.ecf"/>
<cluster name="src" location=".\src\"> <cluster name="src" location=".\src\">
<cluster name="implementation" location="$|implementation" recursive="true" hidden="true"/> <cluster name="implementation" location="$|implementation\" recursive="true" hidden="true"/>
<cluster name="parameters" location="$|parameters" recursive="true"/> <cluster name="parameters" location="$|parameters\" recursive="true"/>
<cluster name="spec_null" location="$|spec\null\" recursive="true"/> <cluster name="spec_null" location="$|spec\null\" recursive="true"/>
<cluster name="spec_net" location="$|spec\net\"> <cluster name="spec_net" location="$|spec\net\">
<condition> <condition>

View File

@@ -7,8 +7,6 @@
<exclude>/\.svn$</exclude> <exclude>/\.svn$</exclude>
<exclude>/EIFGENs$</exclude> <exclude>/EIFGENs$</exclude>
</file_rule> </file_rule>
<option warning="true">
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="curl" location="$ISE_LIBRARY\library\cURL\cURL.ecf"/> <library name="curl" location="$ISE_LIBRARY\library\cURL\cURL.ecf"/>
<library name="encoder" location="..\..\text\encoder\encoder.ecf"/> <library name="encoder" location="..\..\text\encoder\encoder.ecf"/>
@@ -16,8 +14,8 @@
<library name="net" location="$ISE_LIBRARY\library\net\net.ecf"/> <library name="net" location="$ISE_LIBRARY\library\net\net.ecf"/>
<library name="uri" location="$ISE_LIBRARY\library\text\uri\uri.ecf"/> <library name="uri" location="$ISE_LIBRARY\library\text\uri\uri.ecf"/>
<cluster name="src" location=".\src\"> <cluster name="src" location=".\src\">
<cluster name="implementation" location="$|implementation" recursive="true" hidden="true"/> <cluster name="implementation" location="$|implementation\" recursive="true" hidden="true"/>
<cluster name="parameters" location="$|parameters" recursive="true"/> <cluster name="parameters" location="$|parameters\" recursive="true"/>
<cluster name="spec_libcurl" location="$|spec\libcurl\" recursive="true"/> <cluster name="spec_libcurl" location="$|spec\libcurl\" recursive="true"/>
<cluster name="default_libcurl" location="$|default\libcurl\"/> <cluster name="default_libcurl" location="$|default\libcurl\"/>
</cluster> </cluster>

View File

@@ -7,8 +7,6 @@
<exclude>/\.svn$</exclude> <exclude>/\.svn$</exclude>
<exclude>/EIFGENs$</exclude> <exclude>/EIFGENs$</exclude>
</file_rule> </file_rule>
<option warning="true">
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="encoder" location="..\..\text\encoder\encoder.ecf"/> <library name="encoder" location="..\..\text\encoder\encoder.ecf"/>
<library name="http" location="..\protocol\http\http.ecf"/> <library name="http" location="..\protocol\http\http.ecf"/>
@@ -25,8 +23,8 @@
</library> </library>
<library name="uri" location="$ISE_LIBRARY\library\text\uri\uri.ecf"/> <library name="uri" location="$ISE_LIBRARY\library\text\uri\uri.ecf"/>
<cluster name="src" location=".\src\"> <cluster name="src" location=".\src\">
<cluster name="implementation" location="$|implementation" recursive="true" hidden="true"/> <cluster name="implementation" location="$|implementation\" recursive="true" hidden="true"/>
<cluster name="parameters" location="$|parameters" recursive="true"/> <cluster name="parameters" location="$|parameters\" recursive="true"/>
<cluster name="spec_net" location="$|spec\net\"> <cluster name="spec_net" location="$|spec\net\">
<cluster name="net_implementation" location="$|implementation\" hidden="true"/> <cluster name="net_implementation" location="$|implementation\" hidden="true"/>
</cluster> </cluster>

View File

@@ -1,22 +1,20 @@
package http_client package http_client
project project
http_client = "http_client-safe.ecf"
http_client = "http_client.ecf" http_client = "http_client.ecf"
libcurl_http_client = "libcurl_http_client-safe.ecf"
libcurl_http_client = "libcurl_http_client.ecf" libcurl_http_client = "libcurl_http_client.ecf"
net_http_client = "net_http_client-safe.ecf"
net_http_client = "net_http_client.ecf" net_http_client = "net_http_client.ecf"
note note
title: HTTP client title: HTTP client
description: "[ description: "[
Provides simple routines to perform http requests, and get associated response. Provides simple routines to perform http requests, and get associated response.
It has two implementations: It has two implementations:
- using Eiffel cURL (i.e libcurl) - using Eiffel cURL (i.e libcurl)
- using EiffelNET (and the EiffelNET SSL extension) - using EiffelNET (and the EiffelNET SSL extension)
]" ]"
collection:EWF
collection: EWF
tags: http,client,network,request,web,curl,EWF tags: http,client,network,request,web,curl,EWF
copyright: 1984-2016 Eiffel Software and others copyright: 1984-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)

View File

@@ -16,8 +16,19 @@ feature -- Access
deferred deferred
end end
get (a_url: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_RESPONSE
do
Result := new_session (a_url).get ("", ctx)
end
custom (a_method: READABLE_STRING_8; a_url: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_RESPONSE
-- Response for `a_method' request based on `a_url' and optional `ctx'.
do
Result := new_session (a_url).custom (a_method, "", ctx)
end
note note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2017, 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

@@ -30,8 +30,19 @@ feature {NONE} -- Initialization
-- Initialize Current with `a_url' and `ctx'. -- Initialize Current with `a_url' and `ctx'.
-- This can be used to reset/reinitialize Current with new url -- This can be used to reset/reinitialize Current with new url
-- in the case of redirection. -- in the case of redirection.
local
i: INTEGER
do do
url := a_url i := a_url.substring_index ("://", 1)
if i > 0 then
check
a_url.substring (1, i).same_string ("http")
or a_url.substring (1, i).same_string ("https")
end
url := a_url
else
url := session.url (a_url, Void)
end
headers := session.headers.twin headers := session.headers.twin
if ctx /= Void then if ctx /= Void then
context := ctx context := ctx

View File

@@ -272,6 +272,14 @@ feature -- Authentication
-- Associated optional credentials value. -- Associated optional credentials value.
-- Computed as `username':`password'. -- Computed as `username':`password'.
ciphers_setting: detachable READABLE_STRING_8
-- SSL cipher preference lists
-- examples: DEFAULT, ALL, TLSv1
-- check https://www.openssl.org/docs/man1.1.0/apps/ciphers.html
-- Warning: At the moment only used for LIB_CURL_HTTP_CLIENT
-- Net implementation set all the ciphers using the OpenSSL at
-- initialization time.
feature -- Status setting feature -- Status setting
set_is_debug (b: BOOLEAN) set_is_debug (b: BOOLEAN)
@@ -401,6 +409,14 @@ feature -- Element change
chunk_size := a_size chunk_size := a_size
end end
set_ciphers_setting (a_ciphers_setting: READABLE_STRING_8)
-- Set 'ciphers_setting' with 'a_ciphers_setting'.
do
create {STRING_8} ciphers_setting.make_from_string (a_ciphers_setting)
ensure
ciphers_setting_set: attached ciphers_setting as c_setting and then c_setting.same_string (a_ciphers_setting)
end
note note
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2017, 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)"

View File

@@ -206,7 +206,10 @@ feature -- Execution
l_use_curl_form := True l_use_curl_form := True
end end
else else
l_headers.force ("application/x-www-form-urlencoded", "Content-Type")
l_upload_data := ctx.form_parameters_to_x_www_form_url_encoded_string l_upload_data := ctx.form_parameters_to_x_www_form_url_encoded_string
curl_easy.setopt_string (curl_handle, {CURL_OPT_CONSTANTS}.curlopt_postfields, l_upload_data)
curl_easy.setopt_integer (curl_handle, {CURL_OPT_CONSTANTS}.curlopt_postfieldsize, l_upload_data.count)
end end
if l_use_curl_form then if l_use_curl_form then
create l_form.make create l_form.make
@@ -372,6 +375,11 @@ feature -- Execution
curl_easy.setopt_integer (curl_handle, {CURL_OPT_CONSTANTS}.curlopt_ssl_verifypeer, 0) curl_easy.setopt_integer (curl_handle, {CURL_OPT_CONSTANTS}.curlopt_ssl_verifypeer, 0)
end end
--| Cipher List
if attached session.ciphers_setting as c_list then
curl_easy.setopt_string (curl_handle, {CURL_OPT_CONSTANTS}.curlopt_ssl_cipher_list, c_list )
end
--| Request method --| Request method
if request_method.is_case_insensitive_equal ("GET") then if request_method.is_case_insensitive_equal ("GET") then
curl_easy.setopt_integer (curl_handle, {CURL_OPT_CONSTANTS}.curlopt_httpget, 1) curl_easy.setopt_integer (curl_handle, {CURL_OPT_CONSTANTS}.curlopt_httpget, 1)

View File

@@ -113,6 +113,7 @@ feature -- Access
-- Get URL data -- Get URL data
l_is_https := url.starts_with_general ("https://") l_is_https := url.starts_with_general ("https://")
create l_uri.make_from_string (url) create l_uri.make_from_string (url)
check valid_url: l_uri.is_valid end
l_port := l_uri.port l_port := l_uri.port
if l_port = 0 then if l_port = 0 then
if l_is_https then if l_is_https then

View File

@@ -7,117 +7,32 @@
<exclude>/\.svn$</exclude> <exclude>/\.svn$</exclude>
<exclude>/EIFGENs$</exclude> <exclude>/EIFGENs$</exclude>
</file_rule> </file_rule>
<option warning="true"> <external_include location="$ECF_CONFIG_PATH/spec/include"/>
</option>
<external_include location="$ECF_CONFIG_PATH/spec/include">
<condition>
<version type="compiler" min="16.9.9.9124"/>
</condition>
</external_include>
<external_include location="$ECF_CONFIG_PATH/spec/include_until_16_05">
<condition>
<version type="compiler" max="16.9.9.9124"/>
</condition>
</external_include>
<external_include location="$(ISE_LIBRARY)/unstable/library/network/socket/netssl/spec/include">
<condition>
<platform excluded_value="windows"/>
<version type="compiler" max="16.9.9.9124"/>
<custom name="ssl_enabled" value="true"/>
</condition>
</external_include>
<external_include location="$(ISE_LIBRARY)\unstable\library\network\socket\netssl\spec\include">
<condition>
<platform value="windows"/>
<version type="compiler" max="16.9.9.9124"/>
<custom name="ssl_enabled" value="true"/>
</condition>
</external_include>
<external_cflag value="-D_WINSOCKAPI_">
<condition>
<platform value="windows"/>
<version type="compiler" max="16.9.9.9124"/>
<custom name="ssl_enabled" value="true"/>
</condition>
</external_cflag>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="net" location="$ISE_LIBRARY\library\net\net.ecf"/> <library name="net" location="$ISE_LIBRARY\library\net\net.ecf"/>
<library name="net_ssl" location="$ISE_LIBRARY\unstable\library\network\socket\netssl\net_ssl.ecf"> <library name="net_ssl" location="$ISE_LIBRARY\unstable\library\network\socket\netssl\net_ssl.ecf">
<condition> <condition>
<custom name="ssl_enabled" value="true"/> <custom name="ssl_enabled" value="true"/>
</condition> </condition>
</library>
<library name="openssl" location="$ISE_LIBRARY\unstable\library\network\openssl\openssl.ecf">
<condition> <condition>
<custom name="net_ssl_enabled" value="true"/> <version type="compiler" min="17.10.0.0"/>
</condition> <custom name="ssl_enabled" value="true"/>
<condition>
<custom name="httpd_ssl_enabled" value="true"/>
</condition> </condition>
</library> </library>
<cluster name="network" location=".\src\"> <cluster name="network" location=".\src\">
<file_rule>
<exclude>/http_stream_socket_ext.e$</exclude>
<condition>
<version type="compiler" max="17.02"/>
</condition>
</file_rule>
<cluster name="disabled_ssl_network" location="$|no_ssl\" recursive="true"> <cluster name="disabled_ssl_network" location="$|no_ssl\" recursive="true">
<condition> <condition>
<custom name="ssl_enabled" excluded_value="true"/> <custom name="ssl_enabled" excluded_value="true"/>
<custom name="net_ssl_enabled" excluded_value="true"/>
<custom name="httpd_ssl_enabled" excluded_value="true"/>
</condition> </condition>
</cluster> </cluster>
<cluster name="ssl_network" location="$|ssl\" recursive="true"> <cluster name="ssl_network" location="$|ssl\" recursive="true">
<condition> <condition>
<custom name="ssl_enabled" value="true"/> <custom name="ssl_enabled" value="true"/>
</condition> </condition>
<condition>
<custom name="net_ssl_enabled" value="true"/>
</condition>
<condition>
<custom name="httpd_ssl_enabled" value="true"/>
</condition>
<file_rule>
<exclude>/http_stream_secure_socket_ext.e$</exclude>
<condition>
<version type="compiler" max="16.9.9.9124"/>
<custom name="ssl_enabled" value="true"/>
</condition>
<condition>
<version type="compiler" max="16.9.9.9124"/>
<custom name="net_ssl_enabled" value="true"/>
</condition>
<condition>
<version type="compiler" max="16.9.9.9124"/>
<custom name="httpd_ssl_enabled" value="true"/>
</condition>
</file_rule>
</cluster> </cluster>
</cluster> </cluster>
<cluster name="network_until_16_05" location=".\src\until_16_05\">
<condition>
<version type="compiler" max="16.9.9.9124"/>
</condition>
<cluster name="ssl_network_until_16_05" location="$|ssl\" recursive="true">
<condition>
<version type="compiler" max="16.9.9.9124"/>
<custom name="ssl_enabled" value="true"/>
</condition>
<condition>
<version type="compiler" max="16.9.9.9124"/>
<custom name="net_ssl_enabled" value="true"/>
</condition>
<condition>
<version type="compiler" max="16.9.9.9124"/>
<custom name="httpd_ssl_enabled" value="true"/>
</condition>
</cluster>
</cluster>
<cluster name="network_until_17_01" location=".\src\until_17_01\">
<condition>
<version type="compiler" min="16.9.9.9124" max="17.02"/>
</condition>
</cluster>
</target> </target>
<target name="http_network_ssl" extends="http_network"> <target name="http_network_ssl" extends="http_network">
<variable name="ssl_enabled" value="true"/> <variable name="ssl_enabled" value="true"/>

View File

@@ -1,52 +0,0 @@
/*
indexing
description: "Functions used by the EiffelWeb http 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_network_h_
#define _ew_network_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

@@ -9,8 +9,6 @@ class
inherit inherit
NETWORK_STREAM_SOCKET NETWORK_STREAM_SOCKET
HTTP_STREAM_SOCKET_EXT
create create
make, make_empty, make, make_empty,
make_client_by_port, make_client_by_address_and_port, make_client_by_port, make_client_by_address_and_port,

View File

@@ -1,21 +0,0 @@
note
description: "[
Extension to HTTPD_STREAM_SOCKET to support backward compatibility.
TO BE REMOVED IN THE FUTURE, When there is no need to support older compilers.
]"
deferred class
HTTP_STREAM_SOCKET_EXT
note
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
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

@@ -55,12 +55,19 @@ feature -- Secure connection Helpers
end end
set_secure_protocol_to_ssl_2_or_3 set_secure_protocol_to_ssl_2_or_3
-- Set `ssl_protocol' with `Ssl_23'. -- Set `ssl_protocol' with `Ssl_23'.
do -- Protocol not supported anymore.
set_secure_protocol ({SSL_PROTOCOL}.Ssl_23) obsolete
end "Use set_secure_protocol_to_tls_1_2 [2017-06-23]."
local
err: DEVELOPER_EXCEPTION
do
create err
err.set_description ("SSL_2 or SSL_3 are not supported anymore, upgrate to TLS set_secure_protocol_to_tls_1_2")
err.raise
end
set_secure_protocol_to_tls_1_0 set_secure_protocol_to_tls_1_0
-- Set `ssl_protocol' with `Tls_1_0'. -- Set `ssl_protocol' with `Tls_1_0'.
do do
set_secure_protocol ({SSL_PROTOCOL}.Tls_1_0) set_secure_protocol ({SSL_PROTOCOL}.Tls_1_0)
@@ -176,7 +183,14 @@ feature -- Output
end end
note note
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat and others" copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
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

@@ -1,174 +0,0 @@
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
HTTP_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
socket_buffer: MANAGED_POINTER
deferred
end
read_socket_buffer: MANAGED_POINTER
do
Result := socket_buffer
end
put_socket_buffer: MANAGED_POINTER
do
Result := socket_buffer
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_network.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_network.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_network.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_network.h%""
alias
"[
send((int) $a_fd, (char *) $buf, (int) $len, (int) 0)
]"
end
end

View File

@@ -1,41 +0,0 @@
note
description: "[
Extension to HTTP_STREAM_SOCKET to support backward compatibility.
TO BE REMOVED IN THE FUTURE, WHEN 16.05 IS OLD.
]"
deferred class
HTTP_STREAM_SECURE_SOCKET_EXT
feature {NONE} -- SSL bridge
ssl_write (a_ssl: SSL; a_pointer: POINTER; a_byte_count: INTEGER): INTEGER
do
-- In delivery until 16.05
-- SSL.write does not return any value!
-- So let's use `c_ssl_write' from Current class
-- instead of:
-- a_ssl.write (a_pointer, a_byte_count)
Result := c_ssl_write (a_ssl.ptr, a_pointer, a_byte_count)
if a_ssl.was_error then
-- Until 16.05, there is no error check for `SSL.write'
-- so nothing can be done here.
if Result >= 0 then
Result := -1
end
end
end
c_ssl_write (an_ssl_ptr: POINTER; buffer: POINTER; nb_bytes: INTEGER_32): INTEGER_32
-- External call to SSL_write
-- (export status {NONE})
external
"C use %"eif_openssl.h%""
alias
"SSL_write"
end
end

View File

@@ -1,29 +0,0 @@
note
description: "[
Extension to HTTPD_STREAM_SOCKET to support backward compatibility.
TO BE REMOVED IN THE FUTURE, WHEN 17.01 IS OLD.
]"
deferred class
HTTP_STREAM_SOCKET_EXT
feature -- Access
socket_buffer: MANAGED_POINTER
deferred
end
read_socket_buffer: MANAGED_POINTER
do
Result := socket_buffer
end
put_socket_buffer: MANAGED_POINTER
do
Result := socket_buffer
end
feature {NONE} -- No-Exception network operation
end

View File

@@ -1,14 +1,14 @@
package content_negotiation package content_negotiation
project project
conneg = "conneg-safe.ecf"
conneg = "conneg.ecf" conneg = "conneg.ecf"
note note
title: CONneg Content Negotiation title: CONneg Content Negotiation
description: "[ description: "[
CONneg is a library that provides utilities to select the best repesentation of a resource for a client where there are multiple representations available. CONneg is a library that provides utilities to select the best repesentation of a resource for a client where there are multiple representations available.
]" ]"
collection: EWF collection: EWF
tags: content,accept,conneg,negotiation,EWF,web,request tags: content,accept,conneg,negotiation,EWF,web,request
copyright: 2011-2016, Javier Velilla, Jocelyn Fiat, Eiffel Software and others copyright: 2011-2016, Javier Velilla, Jocelyn Fiat, Eiffel Software and others

View File

@@ -1,20 +1,20 @@
package http package http
project project
http = "http-safe.ecf"
http = "http.ecf" http = "http.ecf"
note note
title: HTTP protocol title: HTTP protocol
description: "[ description: "[
Collection of interfaces related to HTTP protocol: Collection of interfaces related to HTTP protocol:
- header - header
- status codes, request methods - status codes, request methods
- content type, media type, mime type. - content type, media type, mime type.
- cookie - cookie
- date used in web protocol - date used in web protocol
- file extension mime mapping - file extension mime mapping
]" ]"
collection: EWF collection: EWF
tags: http,web,header,status,method,type,mime,cookie tags: http,web,header,status,method,type,mime,cookie
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)

View File

@@ -1,25 +1,24 @@
package notification_email package notification_email
project project
notification_email = "notification_email-safe.ecf"
notification_email = "notification_email.ecf" notification_email = "notification_email.ecf"
note note
title: Notification Email title: Notification Email
description: "[ description: "[
Abstract interface to send message via various mailers: Abstract interface to send message via various mailers:
- smtp - smtp
- sendmail - sendmail
- external script - external script
- store on local file - store on local file
- ... - ...
]" ]"
collection: EWF collection: EWF
tags: message,smtp,sendmail,mailer tags: message,smtp,sendmail,mailer
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" copyright: 2011-2016, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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)
link[license]: http://www.eiffel.com/licensing/forum.txt link[license]: http://www.eiffel.com/licensing/forum.txt
link[source]: "github" https://github.com/EiffelWebFramework/EWF/tree/master/library/runtime/process/notification_email link[source]: "github" https://github.com/EiffelWebFramework/EWF/tree/master/library/runtime/process/notification_email
end end

View File

@@ -4,10 +4,6 @@
<root all_classes="true"/> <root all_classes="true"/>
<option warning="true"> <option warning="true">
</option> </option>
<capability>
<concurrency support="scoop" use="scoop"/>
<void_safety support="all" use="all"/>
</capability>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto.ecf"/> <library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto.ecf"/>
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder.ecf"/> <library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder.ecf"/>

View File

@@ -6,7 +6,7 @@ project
note note
title: JSON Web Token title: JSON Web Token
description: JSON Web Token description: JSON Web Token
tags:jwt,web,jws,jwe,token,jose tags: jwt,web,jws,jwe,token,jose
copyright: 2011-2017, Jocelyn Fiat, Eiffel Software and others copyright: 2011-2017, Jocelyn Fiat, 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)
link[license]: http://www.eiffel.com/licensing/forum.txt link[license]: http://www.eiffel.com/licensing/forum.txt

View File

@@ -0,0 +1,36 @@
note
description: "Summary description for {JWT_MISMATCHED_ALG_ERROR}."
date: "$Date$"
revision: "$Revision$"
class
JWT_MISMATCHED_ALG_ERROR
inherit
JWT_ERROR
create
make
feature {NONE} -- Initialization
make (a_alg, a_header_alg: READABLE_STRING_8)
do
alg := a_alg
header_alg := a_header_alg
end
feature -- Access
alg: READABLE_STRING_8
header_alg: READABLE_STRING_8
id: STRING = "ALG_MISMATCH"
message: READABLE_STRING_8
do
Result := "Header alg [" + header_alg + "] does not match given alg [" + alg + "]!"
end
end

View File

@@ -59,6 +59,8 @@ feature -- Status report
do do
if attached claimset.issuer as iss then if attached claimset.issuer as iss then
Result := a_issuer = Void or else a_issuer.same_string (iss) Result := a_issuer = Void or else a_issuer.same_string (iss)
else
Result := a_issuer = Void
end end
end end
@@ -66,6 +68,8 @@ feature -- Status report
do do
if attached claimset.audience as aud then if attached claimset.audience as aud then
Result := a_audience = Void or else a_audience.same_string (aud) Result := a_audience = Void or else a_audience.same_string (aud)
else
Result := a_audience = Void
end end
end end
@@ -118,6 +122,11 @@ feature {JWT_UTILITIES} -- Error reporting
l_errors.extend (err) l_errors.extend (err)
end end
report_mismatched_alg_error (alg, a_header_alg: READABLE_STRING_8)
do
report_error (create {JWT_MISMATCHED_ALG_ERROR}.make (alg, a_header_alg))
end
report_unsupported_alg_error (alg: READABLE_STRING_8) report_unsupported_alg_error (alg: READABLE_STRING_8)
do do
report_error (create {JWT_UNSUPPORTED_ALG_ERROR}.make (alg)) report_error (create {JWT_UNSUPPORTED_ALG_ERROR}.make (alg))

View File

@@ -266,11 +266,10 @@ feature {NONE} -- Implementation
base64_hmacsha256 (s: READABLE_STRING_8; a_secret: READABLE_STRING_8): STRING_8 base64_hmacsha256 (s: READABLE_STRING_8; a_secret: READABLE_STRING_8): STRING_8
local local
hs256: HMAC_SHA256 ut: JWT_UTILITIES
do do
create hs256.make_ascii_key (a_secret) create ut
hs256.update_from_string (s) Result := ut.base64_hmacsha256 (s, a_secret)
Result := hs256.base64_digest --lowercase_hexadecimal_string_digest
end end
end end

View File

@@ -1,8 +1,8 @@
note note
description: "Summary description for {JWT_LOADER}." description: "Loader and verifier to JWT token."
author: ""
date: "$Date$" date: "$Date$"
revision: "$Revision$" revision: "$Revision$"
EIS: "name=Known Critical vulnerabilities in JWT libs", "protocol=URI", "src=https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/"
class class
JWT_LOADER JWT_LOADER
@@ -12,9 +12,13 @@ inherit
feature -- Access feature -- Access
token (a_token_input: READABLE_STRING_8; a_secret: READABLE_STRING_8; ctx: detachable JWT_CONTEXT): detachable JWT token (a_token_input: READABLE_STRING_8; a_alg: detachable READABLE_STRING_8; a_verification_key: READABLE_STRING_8; ctx: detachable JWT_CONTEXT): detachable JWT
-- Decoded token from `a_token_input` given the secret `a_secret`, and optional context `ctx` -- Decoded token from `a_token_input` given the verification key `a_verification_key` and optional (but recommended) signature algorithm `a_alg`, and optional context `ctx`
-- used to specify eventual issuer and various parameters. -- used to specify eventual issuer and various parameters.
-- WARNING: passing Void for `a_alg` is not safe, as the server should know which alg he used for tokens,
-- leaving the possibility to use the header alg is dangerous as client may use "none" and then bypass verification!
require
a_valid_alg: a_alg /= Void implies is_supporting_signature_algorithm (a_alg)
local local
jws: JWS jws: JWS
i,j,n: INTEGER i,j,n: INTEGER
@@ -29,20 +33,27 @@ feature -- Access
l_enc_payload := a_token_input.substring (i + 1, j - 1) l_enc_payload := a_token_input.substring (i + 1, j - 1)
l_signature := a_token_input.substring (j + 1, n) l_signature := a_token_input.substring (j + 1, n)
create jws.make_with_json_payload (base64url_decode (l_enc_payload)) create jws.make_with_json_payload (base64url_decode (l_enc_payload))
alg := signature_algorithm_from_encoded_header (l_enc_header) alg := signature_algorithm_from_encoded_header (l_enc_header)
jws.set_algorithm (alg) if a_alg /= Void then
if alg = Void then if alg /= Void and then not alg.is_case_insensitive_equal_general (a_alg) then
-- Use default jws.report_mismatched_alg_error (a_alg, alg)
alg := alg_hs256 else
alg := a_alg
end
else
if alg = Void then
-- Use default
alg := alg_hs256
end
end end
jws.set_algorithm (alg)
check alg_set: alg /= Void end check alg_set: alg /= Void end
if ctx = Void or else not ctx.validation_ignored then if ctx = Void or else not ctx.validation_ignored then
if not is_supporting_signature_algorithm (alg) then if not is_supporting_signature_algorithm (alg) then
jws.report_unsupported_alg_error (alg) jws.report_unsupported_alg_error (alg)
alg := alg_hs256 alg := alg_hs256
end end
if not l_signature.same_string (signature (l_enc_header, l_enc_payload, a_secret, alg)) then if not l_signature.same_string (signature (l_enc_header, l_enc_payload, a_verification_key, alg)) then
jws.report_unverified_token_error jws.report_unverified_token_error
end end
if if

View File

@@ -61,7 +61,33 @@ feature -- Encoding
do do
create hs256.make_ascii_key (a_secret) create hs256.make_ascii_key (a_secret)
hs256.update_from_string (s) hs256.update_from_string (s)
Result := hs256.base64_digest --lowercase_hexadecimal_string_digest -- if Version >= EiffelStudio 17.11 then
-- Result := hs256.base64_digest --lowercase_hexadecimal_string_digest
-- else
Result := base64_bytes_encoded_string (hs256.digest)
-- end
end
feature {NONE} -- Implementation
base64_bytes_encoded_string (a_bytes: SPECIAL [NATURAL_8]): STRING_8
-- Base64 string from `a_bytes`.
--| Note: to be removed when 17.11 is not latest release anymore.
local
s: STRING
i,n: INTEGER
do
from
i := 1
n := a_bytes.count
create s.make (n)
until
i > n
loop
s.append_code (a_bytes[i - 1])
i := i + 1
end
Result := (create {BASE64}).encoded_string (s)
end end
feature -- Decoding feature -- Decoding

View File

@@ -54,7 +54,14 @@ feature -- Test
create jwt_loader create jwt_loader
if attached jwt_loader.token (tok, "secret", Void) as l_tok then -- Use header alg!
if attached jwt_loader.token (tok, Void, "secret", Void) as l_tok then
assert ("no error", not l_tok.has_error)
assert ("same payload", l_tok.claimset.string.same_string (payload))
end
-- Use given alg!
if attached jwt_loader.token (tok, jwt.algorithm, "secret", Void) as l_tok then
assert ("no error", not l_tok.has_error) assert ("no error", not l_tok.has_error)
assert ("same payload", l_tok.claimset.string.same_string (payload)) assert ("same payload", l_tok.claimset.string.same_string (payload))
end end
@@ -96,21 +103,21 @@ feature -- Test
create jwt_loader create jwt_loader
-- Test with validation + exp -- Test with validation + exp
if attached jwt_loader.token (tok, "secret", Void) as l_tok then if attached jwt_loader.token (tok, jwt.algorithm, "secret", Void) as l_tok then
assert ("no error", not l_tok.has_error) assert ("no error", not l_tok.has_error)
assert ("same payload", l_tok.claimset.string.same_string (payload)) assert ("same payload", l_tok.claimset.string.same_string (payload))
end end
create ctx create ctx
ctx.set_time (now) ctx.set_time (now)
if attached jwt_loader.token (tok, "secret", ctx) as l_tok then if attached jwt_loader.token (tok, jwt.algorithm, "secret", ctx) as l_tok then
assert ("no error", not l_tok.has_error) assert ("no error", not l_tok.has_error)
end end
dt := duplicated_time (now) dt := duplicated_time (now)
dt.hour_add (5) dt.hour_add (5)
ctx.set_time (dt) ctx.set_time (dt)
if attached jwt_loader.token (tok, "secret", ctx) as l_tok then if attached jwt_loader.token (tok, jwt.algorithm, "secret", ctx) as l_tok then
assert ("exp error", l_tok.has_error) assert ("exp error", l_tok.has_error)
end end
@@ -122,7 +129,7 @@ feature -- Test
tok := jwt.encoded_string ("secret") tok := jwt.encoded_string ("secret")
ctx.set_time (now) ctx.set_time (now)
if attached jwt_loader.token (tok, "secret", ctx) as l_tok then if attached jwt_loader.token (tok, jwt.algorithm, "secret", ctx) as l_tok then
assert ("has nbf error", l_tok.has_error) assert ("has nbf error", l_tok.has_error)
end end
@@ -130,7 +137,7 @@ feature -- Test
dt.second_add (15) dt.second_add (15)
ctx.set_time (dt) ctx.set_time (dt)
if attached jwt_loader.token (tok, "secret", ctx) as l_tok then if attached jwt_loader.token (tok, jwt.algorithm, "secret", ctx) as l_tok then
assert ("has nbf error", l_tok.has_error) assert ("has nbf error", l_tok.has_error)
end end
@@ -138,31 +145,51 @@ feature -- Test
dt.minute_add (45) dt.minute_add (45)
ctx.set_time (dt) ctx.set_time (dt)
if attached jwt_loader.token (tok, "secret", ctx) as l_tok then if attached jwt_loader.token (tok, jwt.algorithm, "secret", ctx) as l_tok then
assert ("no error", not l_tok.has_error) assert ("no error", not l_tok.has_error)
end end
-- Test Issuer -- Test Issuer
ctx.set_issuer ("urn:foobar") ctx.set_issuer ("urn:foobar")
if attached jwt_loader.token (tok, "secret", ctx) as l_tok then if attached jwt_loader.token (tok, jwt.algorithm, "secret", ctx) as l_tok then
assert ("has iss error", l_tok.has_error) assert ("has iss error", l_tok.has_error)
end end
ctx.set_issuer ("urn:foo") ctx.set_issuer ("urn:foo")
if attached jwt_loader.token (tok, "secret", ctx) as l_tok then if attached jwt_loader.token (tok, jwt.algorithm, "secret", ctx) as l_tok then
assert ("no error", not l_tok.has_error) assert ("no error", not l_tok.has_error)
end end
-- Test Audience -- Test Audience
ctx.set_audience ("urn:foobar") ctx.set_audience ("urn:foobar")
if attached jwt_loader.token (tok, "secret", ctx) as l_tok then if attached jwt_loader.token (tok, jwt.algorithm, "secret", ctx) as l_tok then
assert ("has aud error", l_tok.has_error) assert ("has aud error", l_tok.has_error)
end end
ctx.set_audience ("urn:foo") ctx.set_audience ("urn:foo")
if attached jwt_loader.token (tok, "secret", ctx) as l_tok then if attached jwt_loader.token (tok, jwt.algorithm, "secret", ctx) as l_tok then
assert ("no error", not l_tok.has_error) assert ("no error", not l_tok.has_error)
end end
end end
test_mismatched_alg_jwt
local
jwt: JWS
payload: STRING
tok: STRING
do
payload := "[
{"iss":"joe","exp":1300819380,"http://example.com/is_root":true}
]"
create jwt.make_with_json_payload (payload)
jwt.set_algorithm ("none")
tok := jwt.encoded_string ("secret")
if attached (create {JWT_LOADER}).token (tok, "HS256", "secret", Void) as l_tok then
assert ("no error", not jwt.has_error)
assert ("same payload", l_tok.claimset.string.same_string (payload))
end
end
test_unsecured_jwt test_unsecured_jwt
local local
jwt: JWS jwt: JWS
@@ -177,7 +204,11 @@ feature -- Test
jwt.set_algorithm ("none") jwt.set_algorithm ("none")
tok := jwt.encoded_string ("secret") tok := jwt.encoded_string ("secret")
if attached (create {JWT_LOADER}).token (tok, "secret", Void) as l_tok then if attached (create {JWT_LOADER}).token (tok, "none", "secret", Void) as l_tok then
assert ("no error", not jwt.has_error)
assert ("same payload", l_tok.claimset.string.same_string (payload))
end
if attached (create {JWT_LOADER}).token (tok, Void, "secret", Void) as l_tok then
assert ("no error", not jwt.has_error) assert ("no error", not jwt.has_error)
assert ("same payload", l_tok.claimset.string.same_string (payload)) assert ("same payload", l_tok.claimset.string.same_string (payload))
end end

View File

@@ -2,11 +2,10 @@ package openid
project project
openid = "consumer/openid.ecf" openid = "consumer/openid.ecf"
openid = "consumer/openid-safe.ecf"
note note
title: Eiffel OpenID title: Eiffel OpenID
description: OpenID consumer library description: OpenID consumer library
tags: openid,security,web,authentication,sso tags: openid,security,web,authentication,sso
copyright: 2011-2016, Jocelyn Fiat, Eiffel Software and others copyright: 2011-2016, Jocelyn Fiat, 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)
@@ -15,4 +14,3 @@ note
link[doc]: "Documentation" https://github.com/EiffelWebFramework/EWF/tree/master/library/security/http_authorization/README.md link[doc]: "Documentation" https://github.com/EiffelWebFramework/EWF/tree/master/library/security/http_authorization/README.md
end end

View File

@@ -1,14 +1,14 @@
package http_authorization package http_authorization
project project
http_authorization = "http_authorization-safe.ecf"
http_authorization = "http_authorization.ecf" http_authorization = "http_authorization.ecf"
note note
title: HTTP Authorization title: HTTP Authorization
description: "[ description: "[
Class to manipulate HTTP 'Authorization' header value. Class to manipulate HTTP 'Authorization' header value.
]" ]"
collection: EWF collection: EWF
tags: http,authorization,authentication,web tags: http,authorization,authentication,web
copyright: 2011-2016, Jocelyn Fiat, Eiffel Software and others copyright: 2011-2016, Jocelyn Fiat, Eiffel Software and others
@@ -17,4 +17,3 @@ note
link[source]: "github" https://github.com/EiffelWebFramework/EWF/tree/master/library/server/authentication/http_authorization link[source]: "github" https://github.com/EiffelWebFramework/EWF/tree/master/library/server/authentication/http_authorization
end end

View File

@@ -76,13 +76,13 @@ feature -- Initialization
a_http_authorization /= Void implies http_authorization /= Void a_http_authorization /= Void implies http_authorization /= Void
end end
make_basic_auth (u: READABLE_STRING_32; p: READABLE_STRING_32) make_basic_auth (u: READABLE_STRING_GENERAL; p: READABLE_STRING_GENERAL)
-- Create a Basic authentication. -- Create a Basic authentication.
do do
make_custom_auth (u, p, Basic_auth_type) make_custom_auth (u, p, Basic_auth_type)
end end
make_custom_auth (u: READABLE_STRING_32; p: READABLE_STRING_32; a_type: READABLE_STRING_8) make_custom_auth (u: READABLE_STRING_GENERAL; p: READABLE_STRING_GENERAL; a_type: READABLE_STRING_8)
-- Create a custom `a_type' authentication. -- Create a custom `a_type' authentication.
require require
a_type_accepted: a_type.is_case_insensitive_equal (Basic_auth_type) a_type_accepted: a_type.is_case_insensitive_equal (Basic_auth_type)
@@ -90,15 +90,20 @@ feature -- Initialization
local local
t: STRING_8 t: STRING_8
utf: UTF_CONVERTER utf: UTF_CONVERTER
s: STRING_32
do do
login := u create login.make_from_string_general (u)
password := p create password.make_from_string_general (p)
create t.make_from_string (a_type) create t.make_from_string (a_type)
t.left_adjust; t.right_adjust t.left_adjust; t.right_adjust
type := t type := t
if t.is_case_insensitive_equal (Basic_auth_type) then if t.is_case_insensitive_equal (Basic_auth_type) then
type := Basic_auth_type type := Basic_auth_type
create http_authorization.make_from_string ("Basic " + (create {BASE64}).encoded_string (utf.string_32_to_utf_8_string_8 (u + {STRING_32} ":" + p))) create s.make_from_string_general (u)
s.extend (':')
s.append_string_general (p)
create http_authorization.make_from_string ("Basic " + (create {BASE64}).encoded_string (utf.string_32_to_utf_8_string_8 (s)))
elseif t.is_case_insensitive_equal (Digest_auth_type) then elseif t.is_case_insensitive_equal (Digest_auth_type) then
type := Digest_auth_type type := Digest_auth_type
to_implement ("HTTP Authorization %""+ t +"%", not yet implemented") to_implement ("HTTP Authorization %""+ t +"%", not yet implemented")
@@ -115,9 +120,9 @@ feature -- Access
type: READABLE_STRING_8 type: READABLE_STRING_8
login: detachable READABLE_STRING_32 login: detachable IMMUTABLE_STRING_32
password: detachable READABLE_STRING_32 password: detachable IMMUTABLE_STRING_32
feature -- Status report feature -- Status report

View File

@@ -1,24 +1,20 @@
package ewsgi package ewsgi
project project
ewsgi = "ewsgi-safe.ecf"
ewsgi = "ewsgi.ecf" ewsgi = "ewsgi.ecf"
connector_cgi = "connectors/cgi/cgi-safe.ecf"
connector_cgi = "connectors/cgi/cgi.ecf" connector_cgi = "connectors/cgi/cgi.ecf"
connector_libfcgi = "connectors/libfcgi/libfcgi-safe.ecf"
connector_libfcgi = "connectors/libfcgi/libfcgi.ecf" connector_libfcgi = "connectors/libfcgi/libfcgi.ecf"
connector_null = "connectors/null/null-safe.ecf"
connector_null = "connectors/null/null.ecf" connector_null = "connectors/null/null.ecf"
connector_standalone = "connectors/standalone/standalone-safe.ecf"
connector_standalone = "connectors/standalone/standalone.ecf" connector_standalone = "connectors/standalone/standalone.ecf"
httpd = "connectors/standalone/src/httpd/httpd-safe.ecf" ewsgi_spec = "ewsgi_spec.ecf"
httpd = "connectors/standalone/src/httpd/httpd.ecf" connector_nino = "connectors/nino/nino.ecf"
note note
title: EWSGI title: EWSGI
description: "[ description: "[
Eiffel Web Server Gateway Interface (EWSGI) specification, and a few connectors. Eiffel Web Server Gateway Interface (EWSGI) specification, and a few connectors.
]" ]"
collection: EWF collection: EWF
tags: ewsgi,cgi,web,httpd,ewf tags: ewsgi,cgi,web,httpd,ewf
copyright: 2011-2016, Jocelyn Fiat, Eiffel Software and others copyright: 2011-2016, Jocelyn Fiat, Eiffel Software and others
@@ -26,5 +22,5 @@ note
link[license]: http://www.eiffel.com/licensing/forum.txt link[license]: http://www.eiffel.com/licensing/forum.txt
link[source]: "github" https://github.com/EiffelWebFramework/EWF/tree/master/library/server/ewsgi link[source]: "github" https://github.com/EiffelWebFramework/EWF/tree/master/library/server/ewsgi
link[doc]: "Documentation" https://github.com/EiffelWebFramework/EWF/tree/master/library/server/ewsgi/doc link[doc]: "Documentation" https://github.com/EiffelWebFramework/EWF/tree/master/library/server/ewsgi/doc
end
end

View File

@@ -8,19 +8,9 @@ deferred class
inherit inherit
HTTPD_REQUEST_HANDLER_I HTTPD_REQUEST_HANDLER_I
redefine
is_persistent_connection_supported
end
feature -- Status report
is_persistent_connection_supported: BOOLEAN = False
-- <Precursor>
-- When there is no concurrency support, do not try to support
-- persistent connection!
note note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2017, 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

@@ -167,7 +167,7 @@ feature -- Element change
end end
set_socket_timeout (a_nb_seconds: like socket_timeout) set_socket_timeout (a_nb_seconds: like socket_timeout)
-- Set `socket_timeout' with `a_nb_seconds' -- Set `socket_timeout' with `a_nb_seconds'.
do do
socket_timeout := a_nb_seconds socket_timeout := a_nb_seconds
ensure ensure
@@ -175,7 +175,7 @@ feature -- Element change
end end
set_socket_recv_timeout (a_nb_seconds: like socket_recv_timeout) set_socket_recv_timeout (a_nb_seconds: like socket_recv_timeout)
-- Set `socket_recv_timeout' with `a_nb_seconds' -- Set `socket_recv_timeout' with `a_nb_seconds'.
do do
socket_recv_timeout := a_nb_seconds socket_recv_timeout := a_nb_seconds
ensure ensure
@@ -183,7 +183,7 @@ feature -- Element change
end 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
keep_alive_timeout := a_seconds keep_alive_timeout := a_seconds
ensure ensure
@@ -191,7 +191,7 @@ feature -- Element change
end end
set_max_keep_alive_requests (nb: like max_keep_alive_requests) set_max_keep_alive_requests (nb: like max_keep_alive_requests)
-- Set `max_keep_alive_requests' with `nb' -- Set `max_keep_alive_requests' with `nb'.
do do
max_keep_alive_requests := nb max_keep_alive_requests := nb
ensure ensure
@@ -254,7 +254,7 @@ feature -- Element change
end end
mark_secure mark_secure
-- Set is_secure in True -- Set is_secure in True.
do do
set_is_secure (True) set_is_secure (True)
ensure ensure
@@ -287,7 +287,7 @@ feature -- Element change
end end
set_secure_protocol (a_version: NATURAL) set_secure_protocol (a_version: NATURAL)
-- Set `secure_protocol' with `a_version' -- Set `secure_protocol' with `a_version'.
do do
secure_protocol := a_version secure_protocol := a_version
ensure ensure
@@ -295,18 +295,19 @@ feature -- Element change
end end
set_secure_protocol_from_string (a_ssl_version: READABLE_STRING_GENERAL) set_secure_protocol_from_string (a_ssl_version: READABLE_STRING_GENERAL)
-- Set `secure_protocol' with `a_ssl_version' -- Set `secure_protocol' with `a_ssl_version'.
do do
if a_ssl_version.is_case_insensitive_equal ("ssl_2_3") then if a_ssl_version.is_case_insensitive_equal ("tls_1_2") then
set_secure_protocol_to_ssl_2_or_3 set_secure_protocol_to_tls_1_2
elseif a_ssl_version.is_case_insensitive_equal ("tls_1_0") then
set_secure_protocol_to_tls_1_0
elseif a_ssl_version.is_case_insensitive_equal ("tls_1_1") then elseif a_ssl_version.is_case_insensitive_equal ("tls_1_1") then
set_secure_protocol_to_tls_1_1 set_secure_protocol_to_tls_1_1
elseif a_ssl_version.is_case_insensitive_equal ("tls_1_2") then elseif a_ssl_version.is_case_insensitive_equal ("tls_1_0") then
set_secure_protocol_to_tls_1_2 set_secure_protocol_to_tls_1_0
elseif a_ssl_version.is_case_insensitive_equal ("dtls_1_0") then elseif a_ssl_version.is_case_insensitive_equal ("dtls_1_0") then
set_secure_protocol_to_dtls_1_0 set_secure_protocol_to_dtls_1_0
elseif a_ssl_version.is_case_insensitive_equal ("ssl_2_3") then
-- Obsolete!
set_secure_protocol_to_ssl_2_or_3
else -- Default else -- Default
set_secure_protocol_to_tls_1_2 set_secure_protocol_to_tls_1_2
end end
@@ -316,6 +317,8 @@ feature -- SSL Helpers
set_secure_protocol_to_ssl_2_or_3 set_secure_protocol_to_ssl_2_or_3
-- Set `secure_protocol' with `Ssl_23'. -- Set `secure_protocol' with `Ssl_23'.
obsolete
"Use `set_secure_protocol_to_tls_1_2` [2017-06-23]."
deferred deferred
end end

View File

@@ -25,8 +25,8 @@ feature -- Default timeout settings
feature -- Default persistent connection settings feature -- Default persistent connection settings
default_keep_alive_timeout: INTEGER = 15 -- seconds default_keep_alive_timeout: INTEGER = 5 -- seconds
default_max_keep_alive_requests: INTEGER = 100 default_max_keep_alive_requests: INTEGER = 300
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

@@ -7,8 +7,6 @@
<exclude>/\.svn$</exclude> <exclude>/\.svn$</exclude>
<exclude>/EIFGENs$</exclude> <exclude>/EIFGENs$</exclude>
</file_rule> </file_rule>
<option warning="true">
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="http_network" location="..\..\network\http_network\http_network.ecf" readonly="false"/> <library name="http_network" location="..\..\network\http_network\http_network.ecf" readonly="false"/>
<library name="net" location="$ISE_LIBRARY\library\net\net.ecf"/> <library name="net" location="$ISE_LIBRARY\library\net\net.ecf"/>
@@ -16,8 +14,11 @@
<condition> <condition>
<custom name="ssl_enabled" value="true"/> <custom name="ssl_enabled" value="true"/>
</condition> </condition>
</library>
<library name="openssl" location="$ISE_LIBRARY\unstable\library\network\openssl\openssl.ecf">
<condition> <condition>
<custom name="httpd_ssl_enabled" value="true"/> <version type="compiler" min="17.10.0.0"/>
<custom name="ssl_enabled" value="true"/>
</condition> </condition>
</library> </library>
<library name="thread" location="$ISE_LIBRARY\library\thread\thread.ecf"> <library name="thread" location="$ISE_LIBRARY\library\thread\thread.ecf">
@@ -35,16 +36,12 @@
<cluster name="no_ssl" location="$|no_ssl\" recursive="true"> <cluster name="no_ssl" location="$|no_ssl\" recursive="true">
<condition> <condition>
<custom name="ssl_enabled" excluded_value="true"/> <custom name="ssl_enabled" excluded_value="true"/>
<custom name="httpd_ssl_enabled" excluded_value="true"/>
</condition> </condition>
</cluster> </cluster>
<cluster name="ssl" location="$|ssl\" recursive="true"> <cluster name="ssl" location="$|ssl\" recursive="true">
<condition> <condition>
<custom name="ssl_enabled" value="true"/> <custom name="ssl_enabled" value="true"/>
</condition> </condition>
<condition>
<custom name="httpd_ssl_enabled" value="true"/>
</condition>
</cluster> </cluster>
<cluster name="concurrency_none" location="$|concurrency\none\" recursive="true"> <cluster name="concurrency_none" location="$|concurrency\none\" recursive="true">
<condition> <condition>

View File

@@ -140,7 +140,8 @@ feature -- Settings
is_persistent_connection_supported: BOOLEAN is_persistent_connection_supported: BOOLEAN
-- Is persistent connection supported? -- Is persistent connection supported?
do do
Result := {HTTPD_SERVER}.is_persistent_connection_supported and then max_keep_alive_requests > 0 Result := {HTTPD_SERVER}.is_persistent_connection_supported and then
max_keep_alive_requests /= 0 --| `-1` no limit
end end
is_next_persistent_connection_supported: BOOLEAN is_next_persistent_connection_supported: BOOLEAN
@@ -247,7 +248,8 @@ feature -- Execution
l_exit l_exit
loop loop
n := n + 1 n := n + 1
if n >= m then -- If `m` is `-1`, no limit for the number of keep_alive requests.
if m >= 0 and n >= m then
is_next_persistent_connection_supported := False is_next_persistent_connection_supported := False
elseif n > 1 and is_verbose then elseif n > 1 and is_verbose then
log ("Reuse connection (" + n.out + ")", information_level) log ("Reuse connection (" + n.out + ")", information_level)

View File

@@ -1,14 +1,14 @@
package httpd package httpd
project project
httpd = "httpd-safe.ecf"
httpd = "httpd.ecf" httpd = "httpd.ecf"
note note
title: HTTP server title: HTTP server
description: "[ description: "[
Simple HTTP listener and handler, that can be extended easily. Simple HTTP listener and handler, that can be extended easily.
]" ]"
tags: http,httpd,server,web tags: http,httpd,server,web
collection: EWF collection: EWF
copyright: 2011-2016, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others copyright: 2011-2016, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others

View File

@@ -36,9 +36,16 @@ feature -- Access
feature -- SSL Helpers feature -- SSL Helpers
set_secure_protocol_to_ssl_2_or_3 set_secure_protocol_to_ssl_2_or_3
-- Set `secure_protocol' with `Ssl_23'. -- Set `ssl_protocol' with `Ssl_23'.
-- Protocol not supported anymore.
obsolete
"Use set_secure_protocol_to_tls_1_2 [2017-06-23]."
local
err: DEVELOPER_EXCEPTION
do do
set_secure_protocol ({SSL_PROTOCOL}.Ssl_23) create err
err.set_description ("SSL_2 or SSL_3 are not supported anymore, upgrate to TLS set_secure_protocol_to_tls_1_2")
err.raise
end end
set_secure_protocol_to_tls_1_0 set_secure_protocol_to_tls_1_0
@@ -67,7 +74,7 @@ feature -- SSL Helpers
note note
copyright: "2011-2014, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2017, 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

@@ -4,16 +4,16 @@ setup
compile_library = Clib compile_library = Clib
project project
libfcgi = "libfcgi-safe.ecf"
libfcgi = "libfcgi.ecf" libfcgi = "libfcgi.ecf"
note note
title: Eiffel libfcgi wrapper title: Eiffel libfcgi wrapper
description: "[ description: "[
Wrapper on modified libfcgi. Wrapper on modified libfcgi.
(modification: added 64 bits support) (modification: added 64 bits support)
It brings implementation for FCGI protocol. It brings implementation for FCGI protocol.
]" ]"
collection: EWF collection: EWF
tags: fcgi,libfcgi,cgi,http,web,ewf tags: fcgi,libfcgi,cgi,http,web,ewf
copyright: 2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others copyright: 2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others

View File

@@ -66,7 +66,7 @@ feature -- Access: connection
end end
max_tcp_clients: INTEGER assign set_max_tcp_clients max_tcp_clients: INTEGER assign set_max_tcp_clients
-- Listen on socket for at most `queue' connections. -- Listen on socket for at most `max_tcp_clients' connections.
do do
Result := option_integer_value ("max_tcp_clients", 0) Result := option_integer_value ("max_tcp_clients", 0)
end end
@@ -104,11 +104,26 @@ feature -- Access: persistent connection
-- Maximum number of requests allowed per persistent connection. -- Maximum number of requests allowed per persistent connection.
-- Recommended a high setting. -- Recommended a high setting.
-- To disable KeepAlive, set `max_keep_alive_requests' to 0. -- To disable KeepAlive, set `max_keep_alive_requests' to 0.
-- To have no limit, set `max_keep_alive_requests' to -1.
-- By default: {HTTPD_CONFIGURATION_I}.default_max_keep_alive_requests . -- By default: {HTTPD_CONFIGURATION_I}.default_max_keep_alive_requests .
do do
Result := option_integer_value ("max_keep_alive_requests", 0) Result := option_integer_value ("max_keep_alive_requests", 0)
end end
persistent_connection_disabled: BOOLEAN
-- Persistent connection disabled?
-- (or Keep-Alive disabled).
do
Result := max_keep_alive_requests = 0
end
has_unlimited_keep_alive_requests: BOOLEAN
-- Has unlimited count of keep alive requests.
-- i.e no limit of number of requests allowed per persistent connection.
do
Result := max_keep_alive_requests < 0
end
feature -- Access: SSL feature -- Access: SSL
is_secure: BOOLEAN assign set_is_secure is_secure: BOOLEAN assign set_is_secure
@@ -205,6 +220,16 @@ feature -- Element change
set_numeric_option ("max_keep_alive_requests", nb) set_numeric_option ("max_keep_alive_requests", nb)
end end
set_unlimited_keep_alive_requests
do
set_max_keep_alive_requests (-1)
end
disable_persistent_connection
do
set_max_keep_alive_requests (0)
end
set_is_secure (b: BOOLEAN) set_is_secure (b: BOOLEAN)
-- Set secured connection enabled to `b'. -- Set secured connection enabled to `b'.
-- i.e if connection is using SSL/TLS. -- i.e if connection is using SSL/TLS.

View File

@@ -1,40 +1,32 @@
package wsf package wsf
project project
wsf = "wsf-safe.ecf"
wsf = "wsf.ecf" wsf = "wsf.ecf"
wsf_extension = "wsf_extension-safe.ecf"
wsf_extension = "wsf_extension.ecf" wsf_extension = "wsf_extension.ecf"
wsf_policy_driven = "wsf_policy_driven-safe.ecf"
wsf_policy_driven = "wsf_policy_driven.ecf" wsf_policy_driven = "wsf_policy_driven.ecf"
wsf_router_context = "wsf_router_context-safe.ecf"
wsf_router_context = "wsf_router_context.ecf" wsf_router_context = "wsf_router_context.ecf"
wsf_session = "wsf_session-safe.ecf"
wsf_session = "wsf_session.ecf" wsf_session = "wsf_session.ecf"
wsf_cgi = "connector/cgi-safe.ecf"
wsf_cgi = "connector/cgi.ecf" wsf_cgi = "connector/cgi.ecf"
wsf_libfcgi = "connector/libfcgi-safe.ecf"
wsf_libfcgi = "connector/libfcgi.ecf" wsf_libfcgi = "connector/libfcgi.ecf"
wsf_openshift = "connector/openshift-safe.ecf"
default_cgi = "default/cgi-safe.ecf"
default_cgi = "default/cgi.ecf" default_cgi = "default/cgi.ecf"
default_libfcgi = "default/libfcgi-safe.ecf"
default_libfcgi = "default/libfcgi.ecf" default_libfcgi = "default/libfcgi.ecf"
default_openshift = "default/openshift-safe.ecf" default_openshift = "default/openshift.ecf"
wsf_standalone = "connector/standalone-safe.ecf"
wsf_standalone = "connector/standalone.ecf" wsf_standalone = "connector/standalone.ecf"
default_standalone = "default/standalone-safe.ecf"
default_standalone = "default/standalone.ecf" default_standalone = "default/standalone.ecf"
wsf_all = "connector/all.ecf"
wsf_nino = "connector/nino.ecf"
wsf_openshift = "connector/openshift.ecf"
wsf_standalone_websocket = "connector/standalone_websocket.ecf"
default_nino = "default/nino.ecf"
note note
title: Web Server Foundation title: Web Server Foundation
description: "[ description: "[
Core of the Eiffel Web Framework (EWF). Core of the Eiffel Web Framework (EWF).
Provide the request, response, router, ... interfaces. Provide the request, response, router, ... interfaces.
The foundation to build web server application. The foundation to build web server application.
]" ]"
tags: ewf,server,httpd,request,connector,web tags: ewf,server,httpd,request,connector,web
collection: EWF collection: EWF
copyright: 2011-2016, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others copyright: 2011-2016, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others
@@ -44,4 +36,3 @@ note
link[doc]: "Documentation" http://eiffelwebframework.github.io/EWF/ link[doc]: "Documentation" http://eiffelwebframework.github.io/EWF/
end end

View File

@@ -22,7 +22,7 @@ feature {NONE} -- Initialization
feature -- Access feature -- Access
default_value: detachable READABLE_STRING_GENERAL default_value: detachable READABLE_STRING_32
rows: INTEGER rows: INTEGER
@@ -54,9 +54,13 @@ feature -- Element change
end end
end end
set_default_value (v: like default_value) set_default_value (v: detachable READABLE_STRING_GENERAL)
do do
default_value := v if v = Void then
default_value := Void
else
default_value := v.as_string_32
end
end end
feature -- Conversion feature -- Conversion

View File

@@ -1,8 +1,7 @@
note note
description : "Objects that ..." description : "Objects containing widget WSF_WIDGET objects, and add specific form support (notion of form fields)."
author : "$Author$" date: "$Date$"
date : "$Date$" revision: "$Revision$"
revision : "$Revision$"
deferred class deferred class
WSF_FORM_COMPOSITE WSF_FORM_COMPOSITE

View File

@@ -48,7 +48,9 @@ feature -- Access
item (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE item (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
do do
Result := items.item (a_name.as_string_8) if a_name.is_valid_as_string_8 then
Result := items.item (a_name.to_string_8)
end
end end
string_item (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 string_item (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32

View File

@@ -39,7 +39,7 @@ feature -- Element Change
set_max (a_val: INTEGER) set_max (a_val: INTEGER)
-- Set `max' with `a_val'. -- Set `max' with `a_val'.
do do
set_max_string(a_val.out) set_max_string (a_val.out)
ensure ensure
max_set: attached max as l_max implies l_max.same_string (a_val.out) max_set: attached max as l_max implies l_max.same_string (a_val.out)
end end
@@ -94,7 +94,6 @@ feature -- Element Change
step_set: attached step as l_step implies l_step.same_string_general (a_val) step_set: attached step as l_step implies l_step.same_string_general (a_val)
end end
feature {NONE} -- Conversion feature {NONE} -- Conversion
append_numeric_input_attributes_to (a_target: STRING) append_numeric_input_attributes_to (a_target: STRING)
@@ -103,7 +102,7 @@ feature {NONE} -- Conversion
--min --min
if attached min as l_min then if attached min as l_min then
a_target.append (" min=%"") a_target.append (" min=%"")
a_target.append(l_min) a_target.append (l_min)
a_target.append_character ('%"') a_target.append_character ('%"')
end end

View File

@@ -19,7 +19,7 @@ feature {NONE} -- Initialization
name := a_name name := a_name
end end
make_with_text (a_name: like name; a_text: READABLE_STRING_32) make_with_text (a_name: like name; a_text: READABLE_STRING_GENERAL)
do do
make (a_name) make (a_name)
set_text_value (a_text) set_text_value (a_text)
@@ -44,7 +44,7 @@ feature -- Access
feature -- Element change feature -- Element change
set_text_value (s: detachable READABLE_STRING_32) set_text_value (s: detachable READABLE_STRING_GENERAL)
do do
set_default_value (s) set_default_value (s)
end end
@@ -73,9 +73,13 @@ feature -- Element change
end end
end end
set_default_value (v: like default_value) set_default_value (v: detachable READABLE_STRING_GENERAL)
do do
default_value := v if v = Void then
default_value := Void
else
default_value := v.as_string_32
end
end end
feature -- Conversion feature -- Conversion

View File

@@ -35,12 +35,17 @@ feature -- Access
feature -- Change element feature -- Change element
set_placeholder (a_placeholder: READABLE_STRING_32) set_placeholder (a_placeholder: detachable READABLE_STRING_GENERAL)
-- Set `placeholder' with `a_placeholder'. -- Set `placeholder' with `a_placeholder'.
do do
placeholder := a_placeholder if a_placeholder = Void then
placeholder := Void
else
placeholder := a_placeholder.as_string_32
end
ensure ensure
placeholder_set: attached placeholder as l_placeholder implies l_placeholder = a_placeholder placeholder_set: (a_placeholder = Void implies placeholder = Void)
or (a_placeholder /= Void implies (attached placeholder as l_placeholder and then a_placeholder.same_string (l_placeholder)))
end end
enable_autofocus enable_autofocus
@@ -91,16 +96,21 @@ feature -- Change element
required_flase: not required required_flase: not required
end end
set_pattern (a_pattern: READABLE_STRING_32) set_pattern (a_pattern: READABLE_STRING_GENERAL)
-- Set `pattern' with `a_pattern'. -- Set `pattern' with `a_pattern'.
-- Example:[0-9][A-Z]{3} -- Example:[0-9][A-Z]{3}
-- Check HTML5 patterns site. -- Check HTML5 patterns site.
note note
EIS: "name=HTML5 Patterns", "src=http://html5pattern.com/" EIS: "name=HTML5 Patterns", "src=http://html5pattern.com/"
do do
pattern := a_pattern if a_pattern = Void then
pattern := Void
else
pattern := a_pattern.as_string_32
end
ensure ensure
pattern_set: attached pattern as l_pattern implies l_pattern = a_pattern pattern_set: (a_pattern = Void implies pattern = Void) or
a_pattern /= Void implies attached pattern as l_pattern and then a_pattern.same_string (l_pattern)
end end

View File

@@ -43,7 +43,6 @@ feature -- Access
feature -- Element Change feature -- Element Change
set_formnovalidate set_formnovalidate
-- Set formnovalidate to True. -- Set formnovalidate to True.
do do
@@ -60,49 +59,69 @@ feature -- Element Change
formnovalidate_false: not formnovalidate formnovalidate_false: not formnovalidate
end end
set_formaction (a_action: READABLE_STRING_GENERAL) set_formaction (a_action: detachable READABLE_STRING_GENERAL)
-- Set `formaction' with `a_action'. -- Set `formaction' with `a_action'.
-- Example:<input type="submit" value="Submit" formaction="/users"> -- Example:<input type="submit" value="Submit" formaction="/users">
require require
is_valid_as_string_8: a_action.is_valid_as_string_8 is_valid_as_string_8: a_action /= Void implies a_action.is_valid_as_string_8
do do
formaction := a_action.to_string_8 if a_action = Void then
formaction := Void
else
formaction := a_action.to_string_8
end
ensure ensure
formaction_set: attached formaction as l_action implies l_action = a_action formaction_set: (a_action = Void implies formaction = Void)
or (a_action /= Void implies (attached formaction as l_action and then a_action.same_string (l_action)))
end end
set_formenctype (a_enctype: READABLE_STRING_GENERAL) set_formenctype (a_enctype: detachable READABLE_STRING_GENERAL)
-- Set `formenctype' with `a_enctype'. -- Set `formenctype' with `a_enctype'.
-- Example: <input type="submit" value="Submit" formenctype="application/x-www-form-urlencoded"> -- Example: <input type="submit" value="Submit" formenctype="application/x-www-form-urlencoded">
require require
is_valid_as_string_8: a_enctype.is_valid_as_string_8 is_valid_as_string_8: a_enctype /= Void implies a_enctype.is_valid_as_string_8
do do
formenctype := a_enctype.to_string_8 if a_enctype = Void then
formenctype := Void
else
formenctype := a_enctype.to_string_8
end
ensure ensure
formenctype_set: attached formenctype as l_enctype implies l_enctype = a_enctype formenctype_set: (a_enctype = Void implies formenctype = Void)
or (a_enctype /= Void implies (attached formenctype as l_enctype and then a_enctype.same_string (l_enctype)))
end end
set_formmethod (a_method: READABLE_STRING_GENERAL) set_formmethod (a_method: detachable READABLE_STRING_GENERAL)
-- Set `formmethod' with `a_method'. -- Set `formmethod' with `a_method'.
-- Example: <input type="submit" value="Submit" formmethod="POST"> -- Example: <input type="submit" value="Submit" formmethod="POST">
--! require is_valid_method: [PUT, POST, DELETE, GET, ...] --! require is_valid_method: [PUT, POST, DELETE, GET, ...]
require require
is_valid_as_string_8: a_method.is_valid_as_string_8 is_valid_as_string_8: a_method /= Void implies a_method.is_valid_as_string_8
do do
formmethod := a_method.to_string_8 if a_method = Void then
formmethod := Void
else
formmethod := a_method.to_string_8
end
ensure ensure
formmethod_set: attached formmethod as l_method implies l_method = a_method formmethod_set: (a_method = Void implies formmethod = Void)
or (a_method /= Void implies (attached formmethod as l_method and then a_method.same_string (l_method)))
end end
set_formtarget (a_target: READABLE_STRING_GENERAL) set_formtarget (a_target: detachable READABLE_STRING_GENERAL)
-- Set `formtarget' with `a_target'. -- Set `formtarget' with `a_target'.
-- Example: <input type="submit" value="Submit" formtarget="_self"> -- Example: <input type="submit" value="Submit" formtarget="_self">
require require
is_valid_as_string_8: a_target.is_valid_as_string_8 is_valid_as_string_8: a_target /= Void implies a_target.is_valid_as_string_8
do do
formtarget := a_target.to_string_8 if a_target = Void then
formtarget := Void
else
formtarget := a_target.to_string_8
end
ensure ensure
formtarget_set: attached formtarget as l_target implies l_target = a_target formtarget_set: (a_target = Void implies formtarget = Void)
or (a_target /= Void implies (attached formtarget as l_target and then a_target.same_string (l_target)))
end end

View File

@@ -1,8 +1,7 @@
note note
description : "Objects that ..." description : "Objects containing WSF_WIDGET objects."
author : "$Author$" date: "$Date$"
date : "$Date$" revision: "$Revision$"
revision : "$Revision$"
deferred class deferred class
WSF_WIDGET_COMPOSITE WSF_WIDGET_COMPOSITE

View File

@@ -1,19 +1,19 @@
package encoder package encoder
project project
encoder = "encoder-safe.ecf"
encoder = "encoder.ecf" encoder = "encoder.ecf"
note note
title: Text encoders title: Text encoders
description: "[ description: "[
Text encoders used in web technologies: Text encoders used in web technologies:
- HTML encoder - HTML encoder
- XML encoder - XML encoder
- JSON encoder - JSON encoder
- UTF8 - UTF8
- BASE64 - BASE64
]" ]"
collection: EWF collection: EWF
tags: html,xml,percent encoding,web,json,utf tags: html,xml,percent encoding,web,json,utf
copyright: 2011-2016, Jocelyn Fiat, Eiffel Software and others copyright: 2011-2016, Jocelyn Fiat, Eiffel Software and others
@@ -23,4 +23,3 @@ note
link[doc]: "Documentation" https://github.com/EiffelWebFramework/EWF/blob/master/library/text/encoder/README.md link[doc]: "Documentation" https://github.com/EiffelWebFramework/EWF/blob/master/library/text/encoder/README.md
end end

View File

@@ -1,15 +1,15 @@
package feed package feed
project project
feed = "feed-safe.ecf"
feed = "feed.ecf" feed = "feed.ecf"
note note
title: Eiffel FEED parser title: Eiffel FEED parser
description: "[ description: "[
RSS2.0 and ATOM feed parser. RSS2.0 and ATOM feed parser.
Feed visitor including HTML generation from FEED Eiffel objects. Feed visitor including HTML generation from FEED Eiffel objects.
]" ]"
tags: rss,atom,feed,html,generator,parser tags: rss,atom,feed,html,generator,parser
copyright: 2011-2016, Jocelyn Fiat, Eiffel Software and others copyright: 2011-2016, Jocelyn Fiat, 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)

View File

@@ -1,17 +1,17 @@
package uri_template package uri_template
project project
uri_template = "uri_template-safe.ecf"
uri_template = "uri_template.ecf" uri_template = "uri_template.ecf"
note note
title: URI Template title: URI Template
description: "[ description: "[
Implement URI Template as described at http://tools.ietf.org/rfc/rfc6570.txt Implement URI Template as described at http://tools.ietf.org/rfc/rfc6570.txt
Support for URI template string expansion
But also partial URI Template matching
]"
Support for URI template string expansion
But also partial URI Template matching
]"
collection: EWF collection: EWF
tags: uri template,router,generator,url tags: uri template,router,generator,url
copyright: 2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others copyright: 2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others
@@ -21,4 +21,3 @@ note
link[doc]: "Documentation" https://github.com/EiffelWebFramework/EWF/tree/master/library/text/parser/uri_template/README.md link[doc]: "Documentation" https://github.com/EiffelWebFramework/EWF/tree/master/library/text/parser/uri_template/README.md
end end

View File

@@ -1,21 +1,20 @@
package error package error
project project
error = "error-safe.ecf"
error = "error.ecf" error = "error.ecf"
note note
title: Error framework title: Error framework
description: "[ description: "[
Errors and associated handler, to manage errors and also provides a way to synchronize one or many error handlers. Errors and associated handler, to manage errors and also provides a way to synchronize one or many error handlers.
This is convenient to propagate error from a layer to another without adding unwanted dependencies. This is convenient to propagate error from a layer to another without adding unwanted dependencies.
]" ]"
collection: EWF collection: EWF
tags: error,framework tags: error,framework
license: Eiffel Forum License v2 license: Eiffel Forum License v2
copyright: Jocelyn Fiat, Eiffel Software and others. copyright: Jocelyn Fiat, Eiffel Software and others.
link[license]: http://www.eiffel.com/licensing/forum.txt link[license]: http://www.eiffel.com/licensing/forum.txt
link[source]: "github" https://github.com/EiffelWebFramework/EWF/tree/master/library/utility/general/error link[source]: "github" https://github.com/EiffelWebFramework/EWF/tree/master/library/utility/general/error
end end

View File

@@ -26,7 +26,6 @@
</option> </option>
<library name="default_standalone" location="..\..\library\server\wsf\default\standalone.ecf" readonly="false" use_application_options="true"/> <library name="default_standalone" location="..\..\library\server\wsf\default\standalone.ecf" readonly="false" use_application_options="true"/>
<cluster name="src" location="src\" recursive="true"/> <cluster name="src" location="src\" recursive="true"/>
<override name="override" location="override\" recursive="true"/>
</target> </target>
<target name="hello_cgi" extends="hello_dev"> <target name="hello_cgi" extends="hello_dev">
<library name="default_cgi" location="..\..\library\server\wsf\default\cgi.ecf"/> <library name="default_cgi" location="..\..\library\server\wsf\default\cgi.ecf"/>

View File

@@ -6,8 +6,8 @@
<capability> <capability>
<catcall_detection use="none"/> <catcall_detection use="none"/>
</capability> </capability>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="net" location="$ISE_LIBRARY\library\net\net-safe.ecf"/> <library name="net" location="$ISE_LIBRARY\library\net\net.ecf"/>
<cluster name="src" location=".\" recursive="true"/> <cluster name="src" location=".\" recursive="true"/>
</target> </target>
</system> </system>

View File

@@ -0,0 +1,253 @@
note
description: "[
Enter class description here!
]"
class
TEST_APP
inherit
SHARED_EXECUTION_ENVIRONMENT
create
make
feature {NONE} -- Initialization
make
-- Instantiate Current object.
local
h, res: STRING
i: INTEGER
l_test_name: detachable READABLE_STRING_GENERAL
choices: HASH_TABLE [READABLE_STRING_GENERAL, INTEGER]
do
create h.make_empty
h.append_character ((0).to_character_8)
h.append_character ((0).to_character_8)
h.append_character ((255).to_character_8)
h.append_character ((255).to_character_8)
i := 0
if attached execution_environment.arguments.argument (1) as tn then
l_test_name := tn
else
create choices.make (tests.count)
across
tests as ic
loop
i := i + 1
choices.force (ic.key, i)
print (i.out + " - " + ic.key.out + "%N")
end
print (" > ")
io.read_line
res := io.last_string
res.adjust
if
res.is_integer and then
attached choices [res.to_integer] as tn
then
l_test_name := tn
end
end
if
l_test_name /= Void and then
attached tests [l_test_name] as proc
then
proc.call ()
else
print ("Quit...%N")
end
end
port_number: INTEGER = 9090
hostname: STRING = "localhost"
has_error: BOOLEAN
tests: STRING_TABLE [PROCEDURE]
once
create Result.make (10)
Result.force (agent cli_execute_get_request, "get_request")
Result.force (agent execute_get_request (1, 0), "get_request (1,0)")
Result.force (agent execute_get_request (10, 0), "get_request (10,0)")
Result.force (agent execute_get_request (1, 10_000), "get_request (1, 10000)")
Result.force (agent execute_get_request (10, 10_000), "get_request (10, 10000)")
Result.force (agent execute_wait_for_ever, "wait_for_ever")
end
feature -- Execution
wait_ms (a_delay_ms: INTEGER; m: detachable READABLE_STRING_8)
local
i64: INTEGER_64
do
if a_delay_ms > 0 then
if has_error then
print ("[ERROR/WAIT] Skipped due to previous error%N")
else
i64 := a_delay_ms.as_integer_64 * {INTEGER_64} 1_000_000
if m /= Void then
print ("[WAIT] " + i64.out + " nanoseconds -> " + m + "%N")
else
print ("[WAIT] " + i64.out + " nanoseconds.%N")
end
execution_environment.sleep (i64) -- nanoseconds
print ("[WAIT] done.%N")
end
end
end
cli_execute_get_request
local
i,n: INTEGER
rq_nb: INTEGER
sl_val: INTEGER
do
if attached execution_environment.arguments as args then
n := args.argument_count
rq_nb := 1
sl_val := 0
i := 1
if n > i then
if args.argument (i).is_case_insensitive_equal_general ("get_request") then
if n >= i + 1 then
rq_nb := args.argument (i + 1).to_integer
if n >= i + 2 then
sl_val := args.argument (i + 2).to_integer
end
end
execute_get_request (rq_nb, sl_val)
end
end
end
end
execute_get_request (rq_nb: INTEGER; a_delay_ms: INTEGER)
require
rq_nb > 0
local
l_socket: NETWORK_STREAM_SOCKET
l_packet: PACKET
l_header_done, l_done: BOOLEAN
line, txt: READABLE_STRING_8
h: STRING
len: INTEGER
i: INTEGER
do
create l_socket.make_client_by_port (port_number, hostname)
l_socket.connect
from
i := rq_nb
until
i <= 0
loop
i := i - 1
print ("GET /test/"+ i.out +" HTTP/1.1%N")
-- socket_put_string (l_socket, "GET /test/"+ i.out +" HTTP/1.1%R%N")
socket_put_string (l_socket, "GET /test/"+ i.out)
wait_ms (a_delay_ms, "inside GET request line")
socket_put_string (l_socket, " HTTP/1.1%R%N")
wait_ms (a_delay_ms, "before Host")
socket_put_string (l_socket, "Host: localhost:9090%R%N")
wait_ms (a_delay_ms, "before Accept")
socket_put_string (l_socket, "Accept: */*%R%N")
wait_ms (a_delay_ms, "before CRNL")
socket_put_string (l_socket, "%R%N")
wait_ms (a_delay_ms, "before reading!")
if not has_error then
from
l_done := False
l_header_done := False
create h.make_empty
until
l_done
loop
if l_header_done then
l_socket.read_stream (len)
txt := l_socket.last_string
print ("BODY:%N")
print (txt)
print ("%N")
if txt.count /= len then
print ("BAD len: " + txt.count.out + " /= " + len.out + "%N")
end
l_done := True
else
l_socket.read_line
line := l_socket.last_string
if l_socket.was_error then
l_done := True
elseif line.is_empty or (line.count = 1 and line[1] = '%R') then
l_header_done := True
else
if line.starts_with_general ("Content-Length:") then
len := line.substring (16, line.count).to_integer
end
h.append (line)
h.append ("%R%N")
print ("HEADER:")
print (line)
print ("%N")
end
end
end
end
end
end
execute_wait_for_ever
local
l_socket: NETWORK_STREAM_SOCKET
l_packet: PACKET
do
create l_socket.make_client_by_port(9090, "localhost")
l_socket.connect
create l_packet.make(1)
l_packet.put_element('a', 0)
l_socket.send(l_packet, 0)
from
until
not l_socket.is_connected
loop
end
end
socket_put_string (a_socket: NETWORK_STREAM_SOCKET; s: STRING_8)
local
retried: BOOLEAN
t: STRING
i: INTEGER
do
if has_error then
create t.make_from_string (s)
i := t.index_of ('%N', 1)
if i > 0 then
t.keep_head (i - 1)
end
t.adjust
print ("[ERROR] Skip put_string ("+ s +"..)%N")
elseif retried then
has_error := True
else
a_socket.put_string (s)
end
rescue
retried := True
retry
end
end