Added skeleton for Eiffel Net implementation of HTTP_CLIENT solution.

This is work in progress.
This commit is contained in:
2015-03-11 14:58:13 +01:00
parent 061e88c9fe
commit 29b55f36cf
10 changed files with 285 additions and 25 deletions

View File

@@ -6,8 +6,9 @@
* Eiffel cURL library * Eiffel cURL library
* cURL dynamic libraries in the PATH or the current directory (.dll or .so) * cURL dynamic libraries in the PATH or the current directory (.dll or .so)
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.
## Usage ## Usage
## Examples ## Examples

View File

@@ -11,7 +11,7 @@
</option> </option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="curl" location="$ISE_LIBRARY\library\cURL\cURL-safe.ecf"/> <library name="curl" location="$ISE_LIBRARY\library\cURL\cURL-safe.ecf"/>
<library name="encoder" location="..\..\text\encoder\encoder-safe.ecf"/> <library name="encoder" location="../../web/framework/ewf/text/encoder/encoder-safe.ecf"/>
<library name="net" location="$ISE_LIBRARY\library\net\net-safe.ecf"/> <library name="net" location="$ISE_LIBRARY\library\net\net-safe.ecf"/>
<cluster name="src" location=".\src\" recursive="true"/> <cluster name="src" location=".\src\" recursive="true"/>
</target> </target>

View File

@@ -12,7 +12,7 @@
<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="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="../../web/framework/ewf/text/encoder/encoder.ecf"/>
<cluster name="src" location=".\src\" recursive="true"/> <cluster name="src" location=".\src\" recursive="true"/>
</target> </target>
</system> </system>

View File

@@ -14,9 +14,10 @@ inherit
feature {NONE} -- Initialization feature {NONE} -- Initialization
make (a_url: READABLE_STRING_8; a_session: like session; ctx: like context) make (a_url: READABLE_STRING_8; a_request_method: like request_method; a_session: like session; ctx: like context)
-- Initialize `Current'. -- Initialize `Current'.
do do
request_method := a_request_method
session := a_session session := a_session
url := a_url url := a_url
headers := session.headers.twin headers := session.headers.twin
@@ -29,6 +30,8 @@ feature {NONE} -- Initialization
ctx_header_set: ctx /= Void implies across ctx.headers as ctx_h all attached headers.item (ctx_h.key) as v and then v.same_string (ctx_h.item) end ctx_header_set: ctx /= Void implies across ctx.headers as ctx_h all attached headers.item (ctx_h.key) as v and then v.same_string (ctx_h.item) end
end end
feature {NONE} -- Internal
session: HTTP_CLIENT_SESSION session: HTTP_CLIENT_SESSION
context: detachable HTTP_CLIENT_REQUEST_CONTEXT context: detachable HTTP_CLIENT_REQUEST_CONTEXT
@@ -44,13 +47,18 @@ feature -- Status report
feature -- Access feature -- Access
request_method: READABLE_STRING_8 request_method: READABLE_STRING_8
deferred -- Request method associated with Current request.
end
url: READABLE_STRING_8 url: READABLE_STRING_8
headers: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8] headers: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]
response: HTTP_CLIENT_RESPONSE
-- Execute the request and return the response.
-- note: two consecutive calls will trigger two executions!
deferred
end
feature {HTTP_CLIENT_SESSION} -- Execution feature {HTTP_CLIENT_SESSION} -- Execution
import (ctx: HTTP_CLIENT_REQUEST_CONTEXT) import (ctx: HTTP_CLIENT_REQUEST_CONTEXT)
@@ -67,10 +75,6 @@ feature {HTTP_CLIENT_SESSION} -- Execution
end end
end end
execute: HTTP_CLIENT_RESPONSE
deferred
end
feature -- Authentication feature -- Authentication
auth_type: STRING auth_type: STRING
@@ -220,7 +224,7 @@ feature {NONE} -- Utilities: encoding
end end
note note
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -1,6 +1,9 @@
note note
description : "[ description : "[
Specific implementation of HTTP_CLIENT based on Eiffel cURL library Specific implementation of HTTP_CLIENT based on Eiffel cURL library
WARNING: Do not forget to have the dynamic libraries libcurl (.dll or .so)
and related accessible to the executable (i.e in same directory, or in the PATH)
]" ]"
author : "$Author$" author : "$Author$"
date : "$Date$" date : "$Date$"
@@ -13,6 +16,7 @@ inherit
HTTP_CLIENT HTTP_CLIENT
create create
default_create,
make make
feature {NONE} -- Initialization feature {NONE} -- Initialization
@@ -20,6 +24,7 @@ feature {NONE} -- Initialization
make make
-- Initialize `Current'. -- Initialize `Current'.
do do
default_create
end end
feature -- Status feature -- Status
@@ -30,7 +35,7 @@ feature -- Status
end end
note note
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -1,6 +1,9 @@
note note
description: "[ description: "[
Specific implementation of HTTP_CLIENT_REQUEST based on Eiffel cURL library Specific implementation of HTTP_CLIENT_REQUEST based on Eiffel cURL library
WARNING: Do not forget to have the dynamic libraries libcurl (.dll or .so)
and related accessible to the executable (i.e in same directory, or in the PATH)
]" ]"
date: "$Date$" date: "$Date$"
revision: "$Revision$" revision: "$Revision$"
@@ -10,9 +13,8 @@ class
inherit inherit
HTTP_CLIENT_REQUEST HTTP_CLIENT_REQUEST
rename
make as make_request
redefine redefine
make,
session session
end end
@@ -23,8 +25,7 @@ feature {NONE} -- Initialization
make (a_url: READABLE_STRING_8; a_request_method: like request_method; a_session: like session; ctx: like context) make (a_url: READABLE_STRING_8; a_request_method: like request_method; a_session: like session; ctx: like context)
do do
make_request (a_url, a_session, ctx) Precursor (a_url, a_request_method, a_session, ctx)
request_method := a_request_method
apply_workaround apply_workaround
end end
@@ -38,13 +39,10 @@ feature {NONE} -- Initialization
session: LIBCURL_HTTP_CLIENT_SESSION session: LIBCURL_HTTP_CLIENT_SESSION
feature -- Access
request_method: READABLE_STRING_8
feature -- Execution feature -- Execution
execute: HTTP_CLIENT_RESPONSE response: HTTP_CLIENT_RESPONSE
-- <Precursor>
local local
l_result: INTEGER l_result: INTEGER
l_curl_string: detachable CURL_STRING l_curl_string: detachable CURL_STRING
@@ -390,7 +388,7 @@ feature {NONE} -- Implementation
end end
note note
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -1,6 +1,9 @@
note note
description: "[ description: "[
Specific implementation of HTTP_CLIENT_SESSION based on Eiffel cURL library Specific implementation of HTTP_CLIENT_SESSION based on Eiffel cURL library
WARNING: Do not forget to have the dynamic libraries libcurl (.dll or .so)
and related accessible to the executable (i.e in same directory, or in the PATH)
]" ]"
date: "$Date$" date: "$Date$"
revision: "$Revision$" revision: "$Revision$"
@@ -38,7 +41,7 @@ feature -- Custom
req: HTTP_CLIENT_REQUEST req: HTTP_CLIENT_REQUEST
do do
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, a_method, Current, ctx) create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, a_method, Current, ctx)
Result := req.execute Result := req.response
end end
custom_with_upload_data (a_method: READABLE_STRING_8; a_path: READABLE_STRING_8; a_ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT; data: READABLE_STRING_8): HTTP_CLIENT_RESPONSE custom_with_upload_data (a_method: READABLE_STRING_8; a_path: READABLE_STRING_8; a_ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT; data: READABLE_STRING_8): HTTP_CLIENT_RESPONSE
@@ -140,7 +143,7 @@ feature {NONE} -- Implementation
end end
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, a_method, Current, ctx) create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, a_method, Current, ctx)
Result := req.execute Result := req.response
if f /= Void then if f /= Void then
f.delete f.delete
@@ -161,7 +164,7 @@ feature {LIBCURL_HTTP_CLIENT_REQUEST} -- Curl implementation
;note ;note
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -0,0 +1,46 @@
note
description : "[
Specific implementation of HTTP_CLIENT based on Eiffel NET library
WARNING: this is work in progress
]"
author : "$Author$"
date : "$Date$"
revision : "$Revision$"
class
NET_HTTP_CLIENT
inherit
HTTP_CLIENT
create
default_create,
make
feature {NONE} -- Initialization
make
-- Initialize `Current'.
do
default_create
end
feature -- Status
new_session (a_base_url: READABLE_STRING_8): NET_HTTP_CLIENT_SESSION
do
create Result.make (a_base_url)
end
note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -0,0 +1,45 @@
note
description: "[
Specific implementation of HTTP_CLIENT_REQUEST based on Eiffel NET library
]"
date: "$Date$"
revision: "$Revision$"
class
NET_HTTP_CLIENT_REQUEST
inherit
HTTP_CLIENT_REQUEST
redefine
session
end
REFACTORING_HELPER
create
make
feature {NONE} -- Internal
session: NET_HTTP_CLIENT_SESSION
feature -- Access
response: HTTP_CLIENT_RESPONSE
-- <Precursor>
do
to_implement ("implementation based on EiffelNET")
(create {EXCEPTIONS}).die (0)
end
note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -0,0 +1,158 @@
note
description: "[
Specific implementation of HTTP_CLIENT_SESSION based on Eiffel NET library
]"
date: "$Date$"
revision: "$Revision$"
class
NET_HTTP_CLIENT_SESSION
inherit
HTTP_CLIENT_SESSION
create
make
feature {NONE} -- Initialization
initialize
do
end
feature -- Status report
is_available: BOOLEAN = True
-- Is interface usable?
feature -- Custom
custom (a_method: READABLE_STRING_8; a_path: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_RESPONSE
local
req: HTTP_CLIENT_REQUEST
do
create {NET_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, a_method, Current, ctx)
Result := req.response
end
custom_with_upload_data (a_method: READABLE_STRING_8; a_path: READABLE_STRING_8; a_ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT; data: READABLE_STRING_8): HTTP_CLIENT_RESPONSE
do
Result := impl_custom (a_method, a_path, a_ctx, data, Void)
end
custom_with_upload_file (a_method: READABLE_STRING_8; a_path: READABLE_STRING_8; a_ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT; fn: READABLE_STRING_8): HTTP_CLIENT_RESPONSE
do
Result := impl_custom (a_method, a_path, a_ctx, Void, fn)
end
feature -- Helper
get (a_path: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_RESPONSE
do
Result := custom ("GET", a_path, ctx)
end
head (a_path: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_RESPONSE
do
Result := custom ("HEAD", a_path, ctx)
end
post (a_path: READABLE_STRING_8; a_ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT; data: detachable READABLE_STRING_8): HTTP_CLIENT_RESPONSE
do
Result := impl_custom ("POST", a_path, a_ctx, data, Void)
end
post_file (a_path: READABLE_STRING_8; a_ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT; fn: detachable READABLE_STRING_8): HTTP_CLIENT_RESPONSE
do
Result := impl_custom ("POST", a_path, a_ctx, Void, fn)
end
patch (a_path: READABLE_STRING_8; a_ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT; data: detachable READABLE_STRING_8): HTTP_CLIENT_RESPONSE
do
Result := impl_custom ("PATCH", a_path, a_ctx, data, Void)
end
patch_file (a_path: READABLE_STRING_8; a_ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT; fn: detachable READABLE_STRING_8): HTTP_CLIENT_RESPONSE
do
Result := impl_custom ("PATCH", a_path, a_ctx, Void, fn)
end
put (a_path: READABLE_STRING_8; a_ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT; data: detachable READABLE_STRING_8): HTTP_CLIENT_RESPONSE
do
Result := impl_custom ("PUT", a_path, a_ctx, data, Void)
end
put_file (a_path: READABLE_STRING_8; a_ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT; fn: detachable READABLE_STRING_8): HTTP_CLIENT_RESPONSE
do
Result := impl_custom ("PUT", a_path, a_ctx, Void, fn)
end
delete (a_path: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_RESPONSE
do
Result := custom ("DELETE", a_path, ctx)
end
feature {NONE} -- Implementation
impl_custom (a_method: READABLE_STRING_8; a_path: READABLE_STRING_8; a_ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT; data: detachable READABLE_STRING_8; fn: detachable READABLE_STRING_8): HTTP_CLIENT_RESPONSE
local
req: HTTP_CLIENT_REQUEST
ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT
f: detachable RAW_FILE
l_data: detachable READABLE_STRING_8
do
ctx := a_ctx
if data /= Void then
if ctx = Void then
create ctx.make
end
ctx.set_upload_data (data)
end
if fn /= Void then
if ctx = Void then
create ctx.make
end
ctx.set_upload_filename (fn)
end
if ctx /= Void then
l_data := ctx.upload_data
if l_data /= Void and a_method.is_case_insensitive_equal_general ("PUT") then
--| Quick and dirty hack using real file, for PUT uploaded data
--| FIXME [2012-05-23]: better use libcurl for that purpose
if ctx.has_upload_filename then
check put_conflict_file_and_data: False end
end
create f.make_open_write (create {FILE_NAME}.make_temporary_name)
f.put_string (l_data)
f.close
check ctx /= Void then
ctx.set_upload_data (Void)
ctx.set_upload_filename (f.path.name)
end
end
end
create {NET_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, a_method, Current, ctx)
Result := req.response
if f /= Void then
f.delete
end
if l_data /= Void and a_ctx /= Void then
a_ctx.set_upload_filename (Void)
a_ctx.set_upload_data (l_data)
end
end
note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end