Compare commits
8 Commits
18.11
...
es_rev1032
| Author | SHA1 | Date | |
|---|---|---|---|
| 256f7581f1 | |||
| 5df220beef | |||
| 5ff361af54 | |||
| 65525aa112 | |||
| d4bbdea5e4 | |||
| 8260336d6c | |||
| 19c14d28c7 | |||
| f1e8dfa40b |
10
CHANGELOG.md
10
CHANGELOG.md
@@ -10,10 +10,20 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
|
|||||||
### Changed
|
### Changed
|
||||||
### Deprecated
|
### Deprecated
|
||||||
### Removed
|
### 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.
|
- Removed obsolete v0 code.
|
||||||
### Fixed
|
### Fixed
|
||||||
- `error`: Fixed custom error creation, do not create default message, otherwise the info will be duplicated in error output.
|
- `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.
|
- `jwt`: updated indexing notes, and readme.
|
||||||
|
- Removed VDRS(4) errors.
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,5 +2,17 @@ Proxy example
|
|||||||
=============
|
=============
|
||||||
|
|
||||||
Via the `wsf_proxy` library, it is possible to implement a simple reverse proxy service.
|
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, ...
|
||||||
|
|
||||||
|
|||||||
@@ -9,41 +9,66 @@ class
|
|||||||
inherit
|
inherit
|
||||||
WSF_EXECUTION
|
WSF_EXECUTION
|
||||||
|
|
||||||
WSF_URI_REWRITER
|
|
||||||
rename
|
|
||||||
uri as proxy_uri
|
|
||||||
end
|
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
|
|
||||||
feature -- Basic operations
|
feature -- Basic operations
|
||||||
|
|
||||||
execute
|
execute
|
||||||
|
local
|
||||||
|
l_forwarded: BOOLEAN
|
||||||
do
|
do
|
||||||
-- NOTE: please enter the target server uri here
|
-- Hardocoded for the example
|
||||||
-- replace "http://localhost:8080/foobar"
|
if request.server_name.same_string ("foo") then
|
||||||
send_proxy_response ("http://localhost:8080/foobar", Current)
|
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
|
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
|
local
|
||||||
h: WSF_SIMPLE_REVERSE_PROXY_HANDLER
|
h: WSF_SIMPLE_REVERSE_PROXY_HANDLER
|
||||||
do
|
do
|
||||||
create h.make (a_remote)
|
create h.make (a_remote)
|
||||||
h.set_uri_rewriter (a_rewriter)
|
if a_rewriter /= Void then
|
||||||
h.set_uri_rewriter (create {WSF_AGENT_URI_REWRITER}.make (agent proxy_uri))
|
h.set_uri_rewriter (create {WSF_AGENT_URI_REWRITER}.make (a_rewriter))
|
||||||
h.set_timeout (30) -- 30 seconds
|
end
|
||||||
|
h.set_timeout_ns (10_000_000_000) -- 10 seconds
|
||||||
h.set_connect_timeout (5_000) -- milliseconds = 5 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)
|
h.execute (request, response)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Helpers
|
feature -- Helpers
|
||||||
|
|
||||||
proxy_uri (a_request: WSF_REQUEST): STRING
|
uri_for_location_based_proxy (a_location: READABLE_STRING_8; a_request: WSF_REQUEST): STRING
|
||||||
-- Request uri rewriten as url.
|
-- Request uri rewritten as url.
|
||||||
do
|
do
|
||||||
Result := a_request.request_uri
|
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
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -10,9 +10,6 @@ class
|
|||||||
|
|
||||||
inherit
|
inherit
|
||||||
HTTPD_CONNECTION_HANDLER_I
|
HTTPD_CONNECTION_HANDLER_I
|
||||||
redefine
|
|
||||||
initialize
|
|
||||||
end
|
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
|
|||||||
@@ -10,9 +10,6 @@ class
|
|||||||
|
|
||||||
inherit
|
inherit
|
||||||
HTTPD_CONNECTION_HANDLER_I
|
HTTPD_CONNECTION_HANDLER_I
|
||||||
redefine
|
|
||||||
initialize
|
|
||||||
end
|
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
|
|||||||
@@ -12,9 +12,6 @@ deferred class WSF_SKELETON_HANDLER
|
|||||||
inherit
|
inherit
|
||||||
|
|
||||||
WSF_URI_TEMPLATE_HANDLER
|
WSF_URI_TEMPLATE_HANDLER
|
||||||
redefine
|
|
||||||
execute
|
|
||||||
end
|
|
||||||
|
|
||||||
WSF_OPTIONS_POLICY
|
WSF_OPTIONS_POLICY
|
||||||
|
|
||||||
@@ -584,7 +581,7 @@ feature {NONE} -- Implementation
|
|||||||
end
|
end
|
||||||
|
|
||||||
note
|
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)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
source: "[
|
source: "[
|
||||||
Eiffel Software
|
Eiffel Software
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ class
|
|||||||
inherit
|
inherit
|
||||||
WSF_FORM_INPUT
|
WSF_FORM_INPUT
|
||||||
redefine
|
redefine
|
||||||
input_type,
|
|
||||||
append_item_to_html
|
append_item_to_html
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,6 @@ class
|
|||||||
|
|
||||||
inherit
|
inherit
|
||||||
WSF_FORM_INPUT
|
WSF_FORM_INPUT
|
||||||
redefine
|
|
||||||
input_type
|
|
||||||
end
|
|
||||||
|
|
||||||
create
|
create
|
||||||
make,
|
make,
|
||||||
|
|||||||
@@ -6,6 +6,14 @@ note
|
|||||||
class
|
class
|
||||||
WSF_SIMPLE_REVERSE_PROXY_HANDLER
|
WSF_SIMPLE_REVERSE_PROXY_HANDLER
|
||||||
|
|
||||||
|
inherit
|
||||||
|
WSF_TIMEOUT_UTILITIES
|
||||||
|
export
|
||||||
|
{NONE} all
|
||||||
|
end
|
||||||
|
|
||||||
|
ANY
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
|
|
||||||
@@ -14,9 +22,11 @@ feature {NONE} -- Initialization
|
|||||||
make (a_remote_uri: READABLE_STRING_8)
|
make (a_remote_uri: READABLE_STRING_8)
|
||||||
do
|
do
|
||||||
create remote_uri.make_from_string (a_remote_uri)
|
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.
|
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
|
end
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
@@ -33,13 +43,36 @@ feature -- Settings
|
|||||||
connect_timeout: INTEGER assign set_connect_timeout
|
connect_timeout: INTEGER assign set_connect_timeout
|
||||||
-- In milliseconds.
|
-- In milliseconds.
|
||||||
|
|
||||||
timeout: INTEGER assign set_timeout
|
timeout_ns,
|
||||||
-- In seconds.
|
recv_timeout_ns,
|
||||||
|
send_timeout_ns: NATURAL_64
|
||||||
|
|
||||||
is_via_header_supported: BOOLEAN
|
is_via_header_supported: BOOLEAN assign set_header_via
|
||||||
-- Via: header supported.
|
-- "Via:" header supported.
|
||||||
|
-- See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Via
|
||||||
-- Default: True.
|
-- 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
|
feature -- Change
|
||||||
|
|
||||||
set_uri_rewriter (a_rewriter: like uri_rewriter)
|
set_uri_rewriter (a_rewriter: like uri_rewriter)
|
||||||
@@ -47,10 +80,30 @@ feature -- Change
|
|||||||
uri_rewriter := a_rewriter
|
uri_rewriter := a_rewriter
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature -- Timeout Change
|
||||||
|
|
||||||
set_timeout (a_timeout_in_seconds: INTEGER)
|
set_timeout (a_timeout_in_seconds: INTEGER)
|
||||||
-- in seconds.
|
-- in seconds.
|
||||||
do
|
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
|
end
|
||||||
|
|
||||||
set_connect_timeout (a_timeout_in_milliseconds: INTEGER)
|
set_connect_timeout (a_timeout_in_milliseconds: INTEGER)
|
||||||
@@ -59,24 +112,55 @@ feature -- Change
|
|||||||
connect_timeout := a_timeout_in_milliseconds
|
connect_timeout := a_timeout_in_milliseconds
|
||||||
end
|
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'.
|
-- Set `is_via_header_supported' to `b'.
|
||||||
do
|
do
|
||||||
is_via_header_supported := b
|
is_via_header_supported := b
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Execution
|
set_header_x_forwarded (b: BOOLEAN)
|
||||||
|
-- Set `is_x_forwarded_header_supported` to `b`.
|
||||||
proxy_uri (request: WSF_REQUEST): STRING
|
|
||||||
-- URI to query on proxyfied host.
|
|
||||||
do
|
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
|
if attached uri_rewriter as r then
|
||||||
Result := r.uri (request)
|
Result.append (r.uri (req))
|
||||||
else
|
else
|
||||||
Result := request.request_uri
|
Result.append (req.request_uri)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature -- Execution
|
||||||
|
|
||||||
execute (request: WSF_REQUEST; response: WSF_RESPONSE)
|
execute (request: WSF_REQUEST; response: WSF_RESPONSE)
|
||||||
-- Execute reverse proxy request.
|
-- Execute reverse proxy request.
|
||||||
local
|
local
|
||||||
@@ -90,23 +174,25 @@ feature -- Execution
|
|||||||
l_completed: BOOLEAN
|
l_completed: BOOLEAN
|
||||||
l_remote_uri: like remote_uri
|
l_remote_uri: like remote_uri
|
||||||
l_socket_factory: WSF_PROXY_SOCKET_FACTORY
|
l_socket_factory: WSF_PROXY_SOCKET_FACTORY
|
||||||
|
l_forwarded: STRING
|
||||||
|
s: READABLE_STRING_8
|
||||||
do
|
do
|
||||||
l_remote_uri := remote_uri
|
l_remote_uri := remote_uri
|
||||||
create l_socket_factory
|
create l_socket_factory
|
||||||
if not l_socket_factory.is_uri_supported (l_remote_uri) then
|
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 + "]")
|
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_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
|
l_socket.connect
|
||||||
if l_socket.is_connected then
|
if
|
||||||
create l_http_query.make_from_string (request.request_method)
|
l_socket.is_connected and then
|
||||||
l_http_query.append_character (' ')
|
attached l_socket.peer_address as l_socket_peer_address
|
||||||
l_http_query.append (l_remote_uri.path)
|
then
|
||||||
l_http_query.append (proxy_uri (request))
|
l_http_query := forward_http_query (request)
|
||||||
l_http_query.append_character (' ')
|
|
||||||
l_http_query.append (request.server_protocol)
|
|
||||||
if attached request.raw_header_data as l_raw_header then
|
if attached request.raw_header_data as l_raw_header then
|
||||||
i := l_raw_header.substring_index ("%R%N", 1)
|
i := l_raw_header.substring_index ("%R%N", 1)
|
||||||
if i > 0 then
|
if i > 0 then
|
||||||
@@ -115,15 +201,22 @@ feature -- Execution
|
|||||||
else
|
else
|
||||||
create h.make_from_raw_header_data (l_raw_header.to_string_8)
|
create h.make_from_raw_header_data (l_raw_header.to_string_8)
|
||||||
end
|
end
|
||||||
if attached l_remote_uri.host as l_remote_host then
|
s := Void
|
||||||
if l_remote_uri.port > 0 then
|
if is_using_proxy_host then
|
||||||
h.put_header_key_value ("Host", l_remote_host + ":" + l_remote_uri.port.out)
|
if attached request.http_host as l_request_host then
|
||||||
else
|
s := l_request_host
|
||||||
h.put_header_key_value ("Host", l_remote_host)
|
|
||||||
end
|
end
|
||||||
|
elseif attached l_remote_uri.host as l_remote_host then
|
||||||
|
s := l_remote_host
|
||||||
|
if l_remote_uri.port > 0 then
|
||||||
|
s := s + ":" + l_remote_uri.port.out
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if s /= Void then
|
||||||
|
h.put_header_key_value ("Host", s)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Via header
|
-- Proxy related headers
|
||||||
if is_via_header_supported then
|
if is_via_header_supported then
|
||||||
if attached h.item ("Via") as v then
|
if attached h.item ("Via") as v then
|
||||||
l_via := v
|
l_via := v
|
||||||
@@ -131,9 +224,51 @@ feature -- Execution
|
|||||||
else
|
else
|
||||||
create l_via.make_empty
|
create l_via.make_empty
|
||||||
end
|
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)
|
h.put_header_key_value ("Via", l_via)
|
||||||
end
|
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
|
-- Max-Forwards header handling
|
||||||
if attached h.item ("Max-Forwards") as h_max_forward then
|
if attached h.item ("Max-Forwards") as h_max_forward then
|
||||||
@@ -221,6 +356,28 @@ feature -- Execution
|
|||||||
|
|
||||||
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]
|
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
|
-- Info from status line
|
||||||
--| Such as "HTTP/1.1 200 OK" -> ["1.1", 200, "OK"]
|
--| Such as "HTTP/1.1 200 OK" -> ["1.1", 200, "OK"]
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
note
|
note
|
||||||
description : "Objects that ..."
|
description: "Console wizard."
|
||||||
author : "$Author$"
|
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
@@ -140,9 +139,6 @@ feature -- Execution
|
|||||||
end
|
end
|
||||||
|
|
||||||
output_page_item (a_item: WIZARD_PAGE_ITEM)
|
output_page_item (a_item: WIZARD_PAGE_ITEM)
|
||||||
local
|
|
||||||
b: BOOLEAN
|
|
||||||
s: detachable READABLE_STRING_32
|
|
||||||
do
|
do
|
||||||
if attached {WIZARD_PAGE_TEXT_ITEM} a_item as txt then
|
if attached {WIZARD_PAGE_TEXT_ITEM} a_item as txt then
|
||||||
localized_print (txt.text)
|
localized_print (txt.text)
|
||||||
@@ -315,5 +311,4 @@ feature {NONE} -- Implementation
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
note
|
note
|
||||||
description : "Objects that ..."
|
description: "Abstract wizard application."
|
||||||
author : "$Author$"
|
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
@@ -8,8 +7,6 @@ deferred class
|
|||||||
WIZARD_APPLICATION
|
WIZARD_APPLICATION
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
ARGUMENTS
|
|
||||||
|
|
||||||
SHARED_EXECUTION_ENVIRONMENT
|
SHARED_EXECUTION_ENVIRONMENT
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
@@ -18,23 +15,25 @@ feature {NONE} -- Initialization
|
|||||||
-- Initialize `Current'.
|
-- Initialize `Current'.
|
||||||
local
|
local
|
||||||
i,n: INTEGER
|
i,n: INTEGER
|
||||||
s: READABLE_STRING_8
|
s: READABLE_STRING_32
|
||||||
wizard_directory_name: detachable PATH
|
wizard_directory_name: detachable PATH
|
||||||
callback_file_name: detachable PATH
|
callback_file_name: detachable PATH
|
||||||
|
args: ARGUMENTS_32
|
||||||
do
|
do
|
||||||
-- Usage
|
-- Usage
|
||||||
n := argument_count
|
args := execution_environment.arguments
|
||||||
|
n := args.argument_count
|
||||||
if n > 0 then
|
if n > 0 then
|
||||||
from
|
from
|
||||||
i := 1
|
i := 1
|
||||||
until
|
until
|
||||||
i > n
|
i > n
|
||||||
loop
|
loop
|
||||||
s := argument (i)
|
s := args.argument (i)
|
||||||
if s.same_string ("-callback") or s.same_string ("--callback") then
|
if s.same_string_general ("-callback") or s.same_string_general ("--callback") then
|
||||||
i := i + 1
|
i := i + 1
|
||||||
if i <= n then
|
if i <= n then
|
||||||
create callback_file_name.make_from_string (argument (i))
|
create callback_file_name.make_from_string (s)
|
||||||
end
|
end
|
||||||
elseif wizard_directory_name = Void then
|
elseif wizard_directory_name = Void then
|
||||||
create wizard_directory_name.make_from_string (s)
|
create wizard_directory_name.make_from_string (s)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {WIZARD_GENERATOR}."
|
description: "Summary description for {WIZARD_GENERATOR}."
|
||||||
author: ""
|
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
@@ -31,7 +30,7 @@ feature -- Access
|
|||||||
|
|
||||||
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.
|
-- Variables used for template and file name resolved string.
|
||||||
--| i.e to expand ${varname} in file name or file content.
|
--| i.e to expand ${varname} in file name or file content.
|
||||||
--| could be used for other purpose.
|
--| could be used for other purpose.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
note
|
note
|
||||||
description : "Objects that ..."
|
description: "EiffelWeb console wizard application."
|
||||||
author : "$Author$"
|
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
@@ -10,8 +9,6 @@ class
|
|||||||
inherit
|
inherit
|
||||||
CONSOLE_WIZARD_APPLICATION
|
CONSOLE_WIZARD_APPLICATION
|
||||||
|
|
||||||
SHARED_EXECUTION_ENVIRONMENT
|
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {EWF_WIZARD}."
|
description: "Wizard for EiffelWeb projects."
|
||||||
author: ""
|
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
@@ -30,14 +29,17 @@ feature -- Pages
|
|||||||
once
|
once
|
||||||
Result := new_page ("first")
|
Result := new_page ("first")
|
||||||
Result.set_title ("Web Application Wizard")
|
Result.set_title ("Web Application Wizard")
|
||||||
Result.set_subtitle ("Based on the EWF libraries...")
|
Result.set_subtitle ("Based on the EiffelWeb framework...")
|
||||||
Result.add_section_text ("Create Web server application with EWF.")
|
Result.add_section_text ("Create Web server application with EiffelWeb (Framework).")
|
||||||
Result.add_text ("[
|
Result.add_text ("[
|
||||||
|
|
||||||
Using the Eiffel Web Framework (EWF), the generated application
|
Using the EiffelWeb Framework (EWF), build server application for any platforms.
|
||||||
will run on any platforms.
|
Depending on the connector(s), there are dependencies on third-party httpd server.
|
||||||
Depending on the connector(s), you may need to use a
|
(For instance libfcgi requires to setup apache, ...)
|
||||||
third-party httpd server (such as apache, nginx, ...)
|
|
||||||
|
More information at:
|
||||||
|
- http://www.eiffelweb.org/
|
||||||
|
- https://www.eiffel.org/projects/eiffel-web .
|
||||||
|
|
||||||
]")
|
]")
|
||||||
end
|
end
|
||||||
@@ -55,8 +57,8 @@ Please fill in:
|
|||||||
Result.extend (Result.new_string_question ("Project name:", "name", "ASCII name, without space"))
|
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.add_directory_question ("Project location:", "location", "Valid directory path, it will be created if missing")
|
||||||
|
|
||||||
Result.data.force ("ewf_app", "name")
|
Result.data.force ("new_app", "name")
|
||||||
Result.data.force (application.available_directory_path ("ewf_app", application.layout.default_projects_location.extended ("ewf")).name, "location")
|
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)
|
Result.set_validation (agent (a_page: WIZARD_PAGE)
|
||||||
do
|
do
|
||||||
@@ -84,8 +86,8 @@ Web application runs on top of connectors
|
|||||||
Select connectors you want to support:
|
Select connectors you want to support:
|
||||||
]")
|
]")
|
||||||
Result.add_boolean_question ("Standalone", "use_standalone", "Using the standalone Eiffel Web server")
|
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 ("CGI", "use_cgi", "Require to setup associated httpd server")
|
||||||
Result.add_boolean_question ("libFCGI", "use_libfcgi", "Require a 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_standalone")
|
||||||
Result.data.force ("yes", "use_cgi")
|
Result.data.force ("yes", "use_cgi")
|
||||||
@@ -97,10 +99,10 @@ Select connectors you want to support:
|
|||||||
Result := new_page ("standalone_connector")
|
Result := new_page ("standalone_connector")
|
||||||
Result.set_title ("Standalone connector")
|
Result.set_title ("Standalone connector")
|
||||||
Result.set_subtitle ("Set options .")
|
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.add_boolean_question ("Verbose", "verbose", "Verbose output")
|
||||||
|
|
||||||
Result.data.force ("80", "port")
|
Result.data.force ("8080", "port")
|
||||||
Result.data.force ("no", "verbose")
|
Result.data.force ("no", "verbose")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {EWF_WIZARD_GENERATOR}."
|
description: "Summary description for {EWF_WIZARD_GENERATOR}."
|
||||||
author: ""
|
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
@@ -28,9 +27,6 @@ feature -- Execution
|
|||||||
local
|
local
|
||||||
d: DIRECTORY
|
d: DIRECTORY
|
||||||
pdn, dn: PATH
|
pdn, dn: PATH
|
||||||
tfn: PATH
|
|
||||||
res: WIZARD_SUCCEED_RESPONSE
|
|
||||||
-- k: STRING_32
|
|
||||||
do
|
do
|
||||||
collection := a_collection
|
collection := a_collection
|
||||||
if
|
if
|
||||||
@@ -55,10 +51,7 @@ feature -- Execution
|
|||||||
|
|
||||||
recursive_copy_templates (application.layout.resources_location, dn)
|
recursive_copy_templates (application.layout.resources_location, dn)
|
||||||
|
|
||||||
tfn := dn.extended (pn).appended_with_extension ("ecf")
|
send_response (create {WIZARD_SUCCEED_RESPONSE}.make (dn.extended (pn).appended_with_extension ("ecf"), d.path))
|
||||||
create res.make (tfn, d.path)
|
|
||||||
|
|
||||||
send_response (res)
|
|
||||||
else
|
else
|
||||||
send_response (create {WIZARD_FAILED_RESPONSE})
|
send_response (create {WIZARD_FAILED_RESPONSE})
|
||||||
end
|
end
|
||||||
@@ -111,8 +104,8 @@ feature -- Templates
|
|||||||
end
|
end
|
||||||
template_context.set_template_folder (application.layout.templates_location)
|
template_context.set_template_folder (application.layout.templates_location)
|
||||||
create inspectors.make (2)
|
create inspectors.make (2)
|
||||||
inspectors.force (create {WIZARD_DATA_TEMPLATE_INSPECTOR}.register ({detachable WIZARD_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}))
|
inspectors.force (create {WIZARD_PAGE_DATA_TEMPLATE_INSPECTOR}.register (({detachable WIZARD_PAGE_DATA}).name))
|
||||||
tpl.analyze
|
tpl.analyze
|
||||||
tpl.get_output
|
tpl.get_output
|
||||||
across
|
across
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
note
|
note
|
||||||
description: "[
|
description: "Graphical wizard for EiffelWeb projects."
|
||||||
Objects that ...
|
|
||||||
]"
|
|
||||||
author: "$Author$"
|
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
@@ -28,6 +25,8 @@ feature {NONE} -- Initialization
|
|||||||
cons: EWF_CONSOLE_WIZARD_APPLICATION
|
cons: EWF_CONSOLE_WIZARD_APPLICATION
|
||||||
do
|
do
|
||||||
default_create
|
default_create
|
||||||
|
|
||||||
|
-- Initialize ISE_PROJECTS variable with expected EiffelStudio value.
|
||||||
if execution_environment.arguments.index_of_word_option ("-console") > 0 then
|
if execution_environment.arguments.index_of_word_option ("-console") > 0 then
|
||||||
create cons.make
|
create cons.make
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ feature -- Access
|
|||||||
if a_page.page_id.is_case_insensitive_equal_general ("first")
|
if a_page.page_id.is_case_insensitive_equal_general ("first")
|
||||||
or a_page.page_id.is_case_insensitive_equal_general ("final")
|
or a_page.page_id.is_case_insensitive_equal_general ("final")
|
||||||
then
|
then
|
||||||
create lab.make_with_text ("EWF")
|
create lab.make_with_text ("EiffelWeb")
|
||||||
lab.set_foreground_color (colors.white)
|
lab.set_foreground_color (colors.white)
|
||||||
Result.extend (create {GRAPHICAL_WIZARD_PAGE_WIDGET}.make_with_widget (lab))
|
Result.extend (create {GRAPHICAL_WIZARD_PAGE_WIDGET}.make_with_widget (lab))
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -10,17 +10,14 @@
|
|||||||
<option warning="true">
|
<option warning="true">
|
||||||
</option>
|
</option>
|
||||||
<setting name="console_application" value="false"/>
|
<setting name="console_application" value="false"/>
|
||||||
|
<setting name="executable_name" value="wizard"/>
|
||||||
<capability>
|
<capability>
|
||||||
<concurrency support="none" use="none"/>
|
<concurrency support="none" use="none"/>
|
||||||
</capability>
|
</capability>
|
||||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
<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="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="template_smarty" location="$ISE_LIBRARY\contrib\library\text\template\smarty\smarty.ecf" readonly="false"/>
|
||||||
<library name="vision2" location="$ISE_LIBRARY\library\vision2\vision2.ecf">
|
<library name="vision2" location="$ISE_LIBRARY\library\vision2\vision2.ecf"/>
|
||||||
<option>
|
|
||||||
<assertions precondition="true"/>
|
|
||||||
</option>
|
|
||||||
</library>
|
|
||||||
<cluster name="graphical" location=".\src\gui\" recursive="true"/>
|
<cluster name="graphical" location=".\src\gui\" recursive="true"/>
|
||||||
<cluster name="src" location=".\src\" recursive="true">
|
<cluster name="src" location=".\src\" recursive="true">
|
||||||
<file_rule>
|
<file_rule>
|
||||||
|
|||||||
Reference in New Issue
Block a user