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
* 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
## Examples

View File

@@ -11,7 +11,7 @@
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base-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"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>

View File

@@ -12,7 +12,7 @@
<library name="base" location="$ISE_LIBRARY/library/base/base.ecf"/>
<library name="net" location="$ISE_LIBRARY\library\net\net.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"/>
</target>
</system>

View File

@@ -14,9 +14,10 @@ inherit
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'.
do
request_method := a_request_method
session := a_session
url := a_url
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
end
feature {NONE} -- Internal
session: HTTP_CLIENT_SESSION
context: detachable HTTP_CLIENT_REQUEST_CONTEXT
@@ -44,13 +47,18 @@ feature -- Status report
feature -- Access
request_method: READABLE_STRING_8
deferred
end
-- Request method associated with Current request.
url: 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
import (ctx: HTTP_CLIENT_REQUEST_CONTEXT)
@@ -67,10 +75,6 @@ feature {HTTP_CLIENT_SESSION} -- Execution
end
end
execute: HTTP_CLIENT_RESPONSE
deferred
end
feature -- Authentication
auth_type: STRING
@@ -220,7 +224,7 @@ feature {NONE} -- Utilities: encoding
end
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)"
source: "[
Eiffel Software

View File

@@ -1,6 +1,9 @@
note
description : "[
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$"
date : "$Date$"
@@ -13,6 +16,7 @@ inherit
HTTP_CLIENT
create
default_create,
make
feature {NONE} -- Initialization
@@ -20,6 +24,7 @@ feature {NONE} -- Initialization
make
-- Initialize `Current'.
do
default_create
end
feature -- Status
@@ -30,7 +35,7 @@ feature -- Status
end
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)"
source: "[
Eiffel Software

View File

@@ -1,6 +1,9 @@
note
description: "[
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$"
revision: "$Revision$"
@@ -10,9 +13,8 @@ class
inherit
HTTP_CLIENT_REQUEST
rename
make as make_request
redefine
make,
session
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)
do
make_request (a_url, a_session, ctx)
request_method := a_request_method
Precursor (a_url, a_request_method, a_session, ctx)
apply_workaround
end
@@ -38,13 +39,10 @@ feature {NONE} -- Initialization
session: LIBCURL_HTTP_CLIENT_SESSION
feature -- Access
request_method: READABLE_STRING_8
feature -- Execution
execute: HTTP_CLIENT_RESPONSE
response: HTTP_CLIENT_RESPONSE
-- <Precursor>
local
l_result: INTEGER
l_curl_string: detachable CURL_STRING
@@ -390,7 +388,7 @@ feature {NONE} -- Implementation
end
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)"
source: "[
Eiffel Software

View File

@@ -1,6 +1,9 @@
note
description: "[
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$"
revision: "$Revision$"
@@ -38,7 +41,7 @@ feature -- Custom
req: HTTP_CLIENT_REQUEST
do
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, a_method, Current, ctx)
Result := req.execute
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
@@ -140,7 +143,7 @@ feature {NONE} -- Implementation
end
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
f.delete
@@ -161,7 +164,7 @@ feature {LIBCURL_HTTP_CLIENT_REQUEST} -- Curl implementation
;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)"
source: "[
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