Compare commits

..

8 Commits

Author SHA1 Message Date
256f7581f1 Updated changelogs 2019-05-30 16:38:27 +02:00
5df220beef Removed redefinitions that violates VDRS(4). 2019-05-30 16:21:53 +02:00
5ff361af54 Simplified proxy example, no more proxy.conf file.
Added forwarding case based on server name.
2019-01-24 11:19:05 +01:00
65525aa112 updated proxy example's README file. 2019-01-24 09:23:47 +01:00
d4bbdea5e4 Removed unneeded redefine. 2019-01-23 23:50:26 +01:00
8260336d6c Added support for X-Forwarded-For .., and Forwarded header, for the simple proxy implementation.
Also added the possibility to "keep" the original host name.
Updated related example.
2019-01-23 23:46:35 +01:00
19c14d28c7 Updated EiffelWeb wizard. 2018-11-19 19:10:26 +01:00
f1e8dfa40b Updated to use ARGUMENTS_32 as client. 2018-11-19 18:04:35 +01:00
18 changed files with 294 additions and 122 deletions

View File

@@ -10,10 +10,20 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
### Changed
### Deprecated
### Removed
### Fixed
### Security
## [v1.1.1] - 2019-05-30
### Added
- `wsf_proxy`: Added support for X-Forwarded-For .., and Forwarded header, for the simple proxy implementation. Also added the possibility to "keep" the original host name. Updated related example.
### Changed
### Deprecated
### Removed
- Removed obsolete v0 code.
### Fixed
- `error`: Fixed custom error creation, do not create default message, otherwise the info will be duplicated in error output.
- `jwt`: updated indexing notes, and readme.
- Removed VDRS(4) errors.
### Security

View File

@@ -2,5 +2,17 @@ Proxy example
=============
Via the `wsf_proxy` library, it is possible to implement a simple reverse proxy service.
Note: you need to edit the `application_execution.e` file to use proper remote service.
(You can use for instance any of the EWF examples as remote server, or also existing public server).
This example forwards request based on server name, or location as described below:
- if server name is `foo`, forwards to `http://localhost:8080/foo`
- if server name is `bar`, forwards to `http://localhost:8080/bar`
- if path starts with "/search/", forwards to `http://www.google.com/search?q=`
For instance:
- http://foo/a/test -> http://localhost:8080/foo/a/test
- http://localhost:9090/search/eiffel -> http://www.google.com/search?q=eiffel
Notes:
- look at `{APPLICATION_EXECUTION}.execute` for the implementation.
- the `send_proxy_response` implements a general forwarding, but for more advanced need, this could be customized per forwarding. For instance, a specific forwarding, may need the X-Forwarded headers, or to keep the `Host` from the client, ...

View File

@@ -9,41 +9,66 @@ class
inherit
WSF_EXECUTION
WSF_URI_REWRITER
rename
uri as proxy_uri
end
create
make
feature -- Basic operations
execute
local
l_forwarded: BOOLEAN
do
-- NOTE: please enter the target server uri here
-- replace "http://localhost:8080/foobar"
send_proxy_response ("http://localhost:8080/foobar", Current)
-- Hardocoded for the example
if request.server_name.same_string ("foo") then
send_proxy_response ("http://localhost:8080/foo", Void)
l_forwarded := True
elseif request.server_name.same_string ("bar") then
send_proxy_response ("http://localhost:8080/bar", Void)
l_forwarded := True
elseif request.path_info.starts_with_general ("/search/") then
send_proxy_response ("http://www.google.com/search?q=", agent uri_for_location_based_proxy ("/search/", ?))
else
response.send (create {WSF_PAGE_RESPONSE}.make_with_body ("EiffelWeb proxy: not forwarded!"))
end
end
send_proxy_response (a_remote: READABLE_STRING_8; a_rewriter: detachable WSF_URI_REWRITER)
send_proxy_response (a_remote: READABLE_STRING_8; a_rewriter: detachable FUNCTION [WSF_REQUEST, STRING])
local
h: WSF_SIMPLE_REVERSE_PROXY_HANDLER
do
create h.make (a_remote)
h.set_uri_rewriter (a_rewriter)
h.set_uri_rewriter (create {WSF_AGENT_URI_REWRITER}.make (agent proxy_uri))
h.set_timeout (30) -- 30 seconds
if a_rewriter /= Void then
h.set_uri_rewriter (create {WSF_AGENT_URI_REWRITER}.make (a_rewriter))
end
h.set_timeout_ns (10_000_000_000) -- 10 seconds
h.set_connect_timeout (5_000) -- milliseconds = 5 seconds
-- Uncomment following, if you want to provide proxy information
-- h.set_header_via (True)
-- h.set_header_forwarded (True)
-- h.set_header_x_forwarded (True)
-- Uncomment following line to keep the original Host value.
-- h.keep_proxy_host (True)
-- For debug information, uncomment next line
-- response.put_error ("Forwarding to " + h.proxy_url (request))
h.execute (request, response)
end
feature -- Helpers
proxy_uri (a_request: WSF_REQUEST): STRING
-- Request uri rewriten as url.
uri_for_location_based_proxy (a_location: READABLE_STRING_8; a_request: WSF_REQUEST): STRING
-- Request uri rewritten as url.
do
Result := a_request.request_uri
-- If related proxy setting is
-- a_location=/foo -> http://foo.com
-- and if request was http://example.com/foo/bar, it will use http://foo.com/bar
-- so the Result here, is "/bar"
if Result.starts_with (a_location) then
Result.remove_head (a_location.count)
end
end
end

View File

@@ -10,9 +10,6 @@ class
inherit
HTTPD_CONNECTION_HANDLER_I
redefine
initialize
end
create
make

View File

@@ -10,9 +10,6 @@ class
inherit
HTTPD_CONNECTION_HANDLER_I
redefine
initialize
end
create
make

View File

@@ -12,9 +12,6 @@ deferred class WSF_SKELETON_HANDLER
inherit
WSF_URI_TEMPLATE_HANDLER
redefine
execute
end
WSF_OPTIONS_POLICY
@@ -584,7 +581,7 @@ feature {NONE} -- Implementation
end
note
copyright: "2011-2014, Colin Adams, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
copyright: "2011-2019, Colin Adams, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software

View File

@@ -10,7 +10,6 @@ class
inherit
WSF_FORM_INPUT
redefine
input_type,
append_item_to_html
end

View File

@@ -9,9 +9,6 @@ class
inherit
WSF_FORM_INPUT
redefine
input_type
end
create
make,

View File

@@ -6,6 +6,14 @@ note
class
WSF_SIMPLE_REVERSE_PROXY_HANDLER
inherit
WSF_TIMEOUT_UTILITIES
export
{NONE} all
end
ANY
create
make
@@ -14,9 +22,11 @@ feature {NONE} -- Initialization
make (a_remote_uri: READABLE_STRING_8)
do
create remote_uri.make_from_string (a_remote_uri)
timeout := 30 -- seconds. See {NETWORK_SOCKET}.default_timeout
timeout_ns := 30_000_000_000 -- seconds. See {NETWORK_SOCKET}.default_timeout
connect_timeout := 5_000 -- 5 seconds.
is_via_header_supported := True
recv_timeout_ns := 5_000_000_000 -- 5 seconds
send_timeout_ns := 5_000_000_000 -- 5 seconds
is_forwarded_header_supported := True
end
feature -- Access
@@ -33,13 +43,36 @@ feature -- Settings
connect_timeout: INTEGER assign set_connect_timeout
-- In milliseconds.
timeout: INTEGER assign set_timeout
-- In seconds.
timeout_ns,
recv_timeout_ns,
send_timeout_ns: NATURAL_64
is_via_header_supported: BOOLEAN
-- Via: header supported.
is_via_header_supported: BOOLEAN assign set_header_via
-- "Via:" header supported.
-- See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Via
-- Default: True.
is_forwarded_header_supported: BOOLEAN assign set_header_forwarded
-- "Forwarded:" header supported (standard)
-- Forwarded: by=<identifier>;for=<identifier>;host=<host>;proto=<http|https>
-- See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded
-- and https://tools.ietf.org/html/rfc7239#section-4
-- Default: False
is_x_forwarded_header_supported: BOOLEAN assign set_header_x_forwarded
-- "X-Forwarded-For:" header supported (XFF), and related ...
-- See: de-facto standard https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For
-- https://en.wikipedia.org/wiki/X-Forwarded-For
-- Default: False
is_using_proxy_host: BOOLEAN assign keep_proxy_host
-- Do not change the HTTP_HOST.
-- Default: False
feature -- Forwarded header settings
header_forwarded_by: detachable READABLE_STRING_8 assign set_header_forwarded_by
feature -- Change
set_uri_rewriter (a_rewriter: like uri_rewriter)
@@ -47,10 +80,30 @@ feature -- Change
uri_rewriter := a_rewriter
end
feature -- Timeout Change
set_timeout (a_timeout_in_seconds: INTEGER)
-- in seconds.
do
timeout := a_timeout_in_seconds
set_timeout_ns (seconds_to_nanoseconds (a_timeout_in_seconds))
end
set_timeout_ns (a_timeout_ns: NATURAL_64)
-- in nanoseconds.
do
timeout_ns := a_timeout_ns
end
set_recv_timeout_ns (ns: NATURAL_64)
-- in nanoseconds.
do
recv_timeout_ns := ns
end
set_send_timeout_ns (ns: NATURAL_64)
-- in nanoseconds.
do
send_timeout_ns := ns
end
set_connect_timeout (a_timeout_in_milliseconds: INTEGER)
@@ -59,24 +112,55 @@ feature -- Change
connect_timeout := a_timeout_in_milliseconds
end
set_is_via_header_supported (b: BOOLEAN)
feature -- Header Change
set_header_forwarded (b: BOOLEAN)
-- Set `is_forwarded_header_supported` to `b`.
do
is_forwarded_header_supported := b
end
set_header_forwarded_by (a_id: like header_forwarded_by)
do
header_forwarded_by := a_id
end
set_is_via_header_supported,
set_header_via (b: BOOLEAN)
-- Set `is_via_header_supported' to `b'.
do
is_via_header_supported := b
end
feature -- Execution
proxy_uri (request: WSF_REQUEST): STRING
-- URI to query on proxyfied host.
set_header_x_forwarded (b: BOOLEAN)
-- Set `is_x_forwarded_header_supported` to `b`.
do
is_x_forwarded_header_supported := b
end
keep_proxy_host (b: BOOLEAN)
do
is_using_proxy_host := b
end
feature -- Access / information
proxy_url (req: WSF_REQUEST): STRING
-- Proxy forward to `Result` URL.
local
l_remote_uri: like remote_uri
do
l_remote_uri := remote_uri
create Result.make_from_string (l_remote_uri.string)
if attached uri_rewriter as r then
Result := r.uri (request)
Result.append (r.uri (req))
else
Result := request.request_uri
Result.append (req.request_uri)
end
end
feature -- Execution
execute (request: WSF_REQUEST; response: WSF_RESPONSE)
-- Execute reverse proxy request.
local
@@ -90,23 +174,25 @@ feature -- Execution
l_completed: BOOLEAN
l_remote_uri: like remote_uri
l_socket_factory: WSF_PROXY_SOCKET_FACTORY
l_forwarded: STRING
s: READABLE_STRING_8
do
l_remote_uri := remote_uri
create l_socket_factory
if not l_socket_factory.is_uri_supported (l_remote_uri) then
send_error (request, response, {HTTP_STATUS_CODE}.bad_gateway, l_remote_uri.scheme + " is not supported! [for remote " + l_remote_uri.string + "]")
elseif attached l_socket_factory.socket_from_uri (l_remote_uri) as l_socket then
elseif attached {NETWORK_STREAM_SOCKET} l_socket_factory.socket_from_uri (l_remote_uri) as l_socket then
l_socket.set_connect_timeout (connect_timeout) -- milliseconds
l_socket.set_timeout (timeout) -- seconds
l_socket.set_timeout_ns (timeout_ns)
l_socket.set_recv_timeout_ns (recv_timeout_ns)
l_socket.set_send_timeout_ns (send_timeout_ns)
l_socket.connect
if l_socket.is_connected then
create l_http_query.make_from_string (request.request_method)
l_http_query.append_character (' ')
l_http_query.append (l_remote_uri.path)
l_http_query.append (proxy_uri (request))
l_http_query.append_character (' ')
l_http_query.append (request.server_protocol)
if
l_socket.is_connected and then
attached l_socket.peer_address as l_socket_peer_address
then
l_http_query := forward_http_query (request)
if attached request.raw_header_data as l_raw_header then
i := l_raw_header.substring_index ("%R%N", 1)
if i > 0 then
@@ -115,15 +201,22 @@ feature -- Execution
else
create h.make_from_raw_header_data (l_raw_header.to_string_8)
end
if attached l_remote_uri.host as l_remote_host then
s := Void
if is_using_proxy_host then
if attached request.http_host as l_request_host then
s := l_request_host
end
elseif attached l_remote_uri.host as l_remote_host then
s := l_remote_host
if l_remote_uri.port > 0 then
h.put_header_key_value ("Host", l_remote_host + ":" + l_remote_uri.port.out)
else
h.put_header_key_value ("Host", l_remote_host)
s := s + ":" + l_remote_uri.port.out
end
end
if s /= Void then
h.put_header_key_value ("Host", s)
end
-- Via header
-- Proxy related headers
if is_via_header_supported then
if attached h.item ("Via") as v then
l_via := v
@@ -131,9 +224,51 @@ feature -- Execution
else
create l_via.make_empty
end
l_via.append (request.server_protocol + " " + request.server_name + " (PROXY-" + request.server_software + ")")
l_via.append (request.server_protocol)
l_via.append_character (' ')
l_via.append (request.server_name)
l_via.append (" (PROXY-")
l_via.append (request.server_software)
l_via.append_character (')')
h.put_header_key_value ("Via", l_via)
end
if is_forwarded_header_supported then
-- Forwarded: for=<identifier>;host=<host>;proto=<http|https>
create l_forwarded.make (50)
l_forwarded.append ("for=")
l_forwarded.append (request.remote_addr)
if attached request.http_host as l_host then
l_forwarded.append (";host=")
l_forwarded.append (l_host)
end
l_forwarded.append (";proto=")
if request.is_https then
l_forwarded.append ("https")
else
l_forwarded.append ("http")
end
if attached header_forwarded_by as l_id then
l_forwarded.append (";by=")
l_forwarded.append (l_id)
end
if attached request.meta_string_variable ("HTTP_FORWARDED") as l_req_forwarded then
l_forwarded := l_req_forwarded + ", " + l_forwarded
end
h.put_header_key_value ("Forwarded", l_forwarded)
end
if is_x_forwarded_header_supported then
s := request.remote_addr
if attached request.meta_string_variable ("HTTP_X_FORWARDED_FOR") as l_xff then
s := l_xff + ", " + s
end
h.put_header_key_value ("X-Forwarded-For", s)
h.put_header_key_value ("X-Forwarded-Port", request.server_port.out)
if request.is_https then
h.put_header_key_value ("X-Forwarded-Proto", "https")
else
h.put_header_key_value ("X-Forwarded-Proto", "http")
end
end
-- Max-Forwards header handling
if attached h.item ("Max-Forwards") as h_max_forward then
@@ -219,7 +354,29 @@ feature -- Execution
end
end
feature {NONE} -- Implementation
feature {NONE} -- Implementation
forward_http_query (req: WSF_REQUEST): STRING
local
l_remote_uri: like remote_uri
do
l_remote_uri := remote_uri
create Result.make_from_string (req.request_method)
Result.append_character (' ')
Result.append (l_remote_uri.path)
if attached l_remote_uri.query as q then
Result.append_character ('?')
Result.append (q)
end
if attached uri_rewriter as r then
Result.append (r.uri (req))
else
Result.append (req.request_uri)
end
Result.append_character (' ')
Result.append (req.server_protocol)
end
status_line_info (a_line: READABLE_STRING_8): detachable TUPLE [protocol: READABLE_STRING_8; status_code: INTEGER; reason_phrase: detachable READABLE_STRING_8]
-- Info from status line

View File

@@ -1,8 +1,7 @@
note
description : "Objects that ..."
author : "$Author$"
date : "$Date$"
revision : "$Revision$"
description: "Console wizard."
date: "$Date$"
revision: "$Revision$"
deferred class
CONSOLE_WIZARD_APPLICATION
@@ -140,9 +139,6 @@ feature -- Execution
end
output_page_item (a_item: WIZARD_PAGE_ITEM)
local
b: BOOLEAN
s: detachable READABLE_STRING_32
do
if attached {WIZARD_PAGE_TEXT_ITEM} a_item as txt then
localized_print (txt.text)
@@ -315,5 +311,4 @@ feature {NONE} -- Implementation
end
end
end

View File

@@ -1,15 +1,12 @@
note
description : "Objects that ..."
author : "$Author$"
date : "$Date$"
revision : "$Revision$"
description: "Abstract wizard application."
date: "$Date$"
revision: "$Revision$"
deferred class
WIZARD_APPLICATION
inherit
ARGUMENTS
SHARED_EXECUTION_ENVIRONMENT
feature {NONE} -- Initialization
@@ -18,23 +15,25 @@ feature {NONE} -- Initialization
-- Initialize `Current'.
local
i,n: INTEGER
s: READABLE_STRING_8
s: READABLE_STRING_32
wizard_directory_name: detachable PATH
callback_file_name: detachable PATH
args: ARGUMENTS_32
do
-- Usage
n := argument_count
args := execution_environment.arguments
n := args.argument_count
if n > 0 then
from
i := 1
until
i > n
loop
s := argument (i)
if s.same_string ("-callback") or s.same_string ("--callback") then
s := args.argument (i)
if s.same_string_general ("-callback") or s.same_string_general ("--callback") then
i := i + 1
if i <= n then
create callback_file_name.make_from_string (argument (i))
create callback_file_name.make_from_string (s)
end
elseif wizard_directory_name = Void then
create wizard_directory_name.make_from_string (s)

View File

@@ -1,6 +1,5 @@
note
description: "Summary description for {WIZARD_GENERATOR}."
author: ""
date: "$Date$"
revision: "$Revision$"
@@ -31,7 +30,7 @@ feature -- Access
feature -- Access
variables: STRING_TABLE [READABLE_STRING_8]
variables: STRING_TABLE [READABLE_STRING_32]
-- Variables used for template and file name resolved string.
--| i.e to expand ${varname} in file name or file content.
--| could be used for other purpose.

View File

@@ -1,8 +1,7 @@
note
description : "Objects that ..."
author : "$Author$"
date : "$Date$"
revision : "$Revision$"
description: "EiffelWeb console wizard application."
date: "$Date$"
revision: "$Revision$"
class
EWF_CONSOLE_WIZARD_APPLICATION
@@ -10,8 +9,6 @@ class
inherit
CONSOLE_WIZARD_APPLICATION
SHARED_EXECUTION_ENVIRONMENT
create
make

View File

@@ -1,6 +1,5 @@
note
description: "Summary description for {EWF_WIZARD}."
author: ""
description: "Wizard for EiffelWeb projects."
date: "$Date$"
revision: "$Revision$"
@@ -30,14 +29,17 @@ feature -- Pages
once
Result := new_page ("first")
Result.set_title ("Web Application Wizard")
Result.set_subtitle ("Based on the EWF libraries...")
Result.add_section_text ("Create Web server application with EWF.")
Result.set_subtitle ("Based on the EiffelWeb framework...")
Result.add_section_text ("Create Web server application with EiffelWeb (Framework).")
Result.add_text ("[
Using the Eiffel Web Framework (EWF), the generated application
will run on any platforms.
Depending on the connector(s), you may need to use a
third-party httpd server (such as apache, nginx, ...)
Using the EiffelWeb Framework (EWF), build server application for any platforms.
Depending on the connector(s), there are dependencies on third-party httpd server.
(For instance libfcgi requires to setup apache, ...)
More information at:
- http://www.eiffelweb.org/
- https://www.eiffel.org/projects/eiffel-web .
]")
end
@@ -55,8 +57,8 @@ Please fill in:
Result.extend (Result.new_string_question ("Project name:", "name", "ASCII name, without space"))
Result.add_directory_question ("Project location:", "location", "Valid directory path, it will be created if missing")
Result.data.force ("ewf_app", "name")
Result.data.force (application.available_directory_path ("ewf_app", application.layout.default_projects_location.extended ("ewf")).name, "location")
Result.data.force ("new_app", "name")
Result.data.force (application.available_directory_path ("new_app", application.layout.default_projects_location.extended ("eiffelweb")).name, "location")
Result.set_validation (agent (a_page: WIZARD_PAGE)
do
@@ -84,9 +86,9 @@ Web application runs on top of connectors
Select connectors you want to support:
]")
Result.add_boolean_question ("Standalone", "use_standalone", "Using the standalone Eiffel Web server")
Result.add_boolean_question ("CGI", "use_cgi", "Require a httpd server")
Result.add_boolean_question ("libFCGI", "use_libfcgi", "Require a httpd server")
Result.add_boolean_question ("CGI", "use_cgi", "Require to setup associated httpd server")
Result.add_boolean_question ("libFCGI", "use_libfcgi", "Require to setup associated httpd server, and have libfcgi dynamic libraries in the path")
Result.data.force ("yes", "use_standalone")
Result.data.force ("yes", "use_cgi")
Result.data.force ("yes", "use_libfcgi")
@@ -97,10 +99,10 @@ Select connectors you want to support:
Result := new_page ("standalone_connector")
Result.set_title ("Standalone connector")
Result.set_subtitle ("Set options .")
Result.add_integer_question ("Port number", "port", "It happens port 80 is already taken, thus choose another one.")
Result.add_integer_question ("Port number", "port", "If port 8080 is already taken, then choose another one.")
Result.add_boolean_question ("Verbose", "verbose", "Verbose output")
Result.data.force ("80", "port")
Result.data.force ("8080", "port")
Result.data.force ("no", "verbose")
end

View File

@@ -1,6 +1,5 @@
note
description: "Summary description for {EWF_WIZARD_GENERATOR}."
author: ""
date: "$Date$"
revision: "$Revision$"
@@ -28,9 +27,6 @@ feature -- Execution
local
d: DIRECTORY
pdn, dn: PATH
tfn: PATH
res: WIZARD_SUCCEED_RESPONSE
-- k: STRING_32
do
collection := a_collection
if
@@ -55,10 +51,7 @@ feature -- Execution
recursive_copy_templates (application.layout.resources_location, dn)
tfn := dn.extended (pn).appended_with_extension ("ecf")
create res.make (tfn, d.path)
send_response (res)
send_response (create {WIZARD_SUCCEED_RESPONSE}.make (dn.extended (pn).appended_with_extension ("ecf"), d.path))
else
send_response (create {WIZARD_FAILED_RESPONSE})
end
@@ -111,8 +104,8 @@ feature -- Templates
end
template_context.set_template_folder (application.layout.templates_location)
create inspectors.make (2)
inspectors.force (create {WIZARD_DATA_TEMPLATE_INSPECTOR}.register ({detachable WIZARD_DATA}))
inspectors.force (create {WIZARD_PAGE_DATA_TEMPLATE_INSPECTOR}.register ({detachable WIZARD_PAGE_DATA}))
inspectors.force (create {WIZARD_DATA_TEMPLATE_INSPECTOR}.register (({detachable WIZARD_DATA}).name))
inspectors.force (create {WIZARD_PAGE_DATA_TEMPLATE_INSPECTOR}.register (({detachable WIZARD_PAGE_DATA}).name))
tpl.analyze
tpl.get_output
across

View File

@@ -1,8 +1,5 @@
note
description: "[
Objects that ...
]"
author: "$Author$"
description: "Graphical wizard for EiffelWeb projects."
date: "$Date$"
revision: "$Revision$"
@@ -28,6 +25,8 @@ feature {NONE} -- Initialization
cons: EWF_CONSOLE_WIZARD_APPLICATION
do
default_create
-- Initialize ISE_PROJECTS variable with expected EiffelStudio value.
if execution_environment.arguments.index_of_word_option ("-console") > 0 then
create cons.make
else

View File

@@ -29,7 +29,7 @@ feature -- Access
if a_page.page_id.is_case_insensitive_equal_general ("first")
or a_page.page_id.is_case_insensitive_equal_general ("final")
then
create lab.make_with_text ("EWF")
create lab.make_with_text ("EiffelWeb")
lab.set_foreground_color (colors.white)
Result.extend (create {GRAPHICAL_WIZARD_PAGE_WIDGET}.make_with_widget (lab))
end

View File

@@ -10,17 +10,14 @@
<option warning="true">
</option>
<setting name="console_application" value="false"/>
<setting name="executable_name" value="wizard"/>
<capability>
<concurrency support="none" use="none"/>
</capability>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="gui_wizard" location="lib\wizard\estudio_gui_wizard.ecf" readonly="false"/>
<library name="template_smarty" location="$ISE_LIBRARY\contrib\library\text\template\smarty\smarty.ecf" readonly="false"/>
<library name="vision2" location="$ISE_LIBRARY\library\vision2\vision2.ecf">
<option>
<assertions precondition="true"/>
</option>
</library>
<library name="vision2" location="$ISE_LIBRARY\library\vision2\vision2.ecf"/>
<cluster name="graphical" location=".\src\gui\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true">
<file_rule>