Added Module Custom Search
Added Google custom search library Added HTTP client extension libaray Updated demo example to use the Module Custom Search
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-14-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-14-0 http://www.eiffel.com/developers/xml/configuration-1-14-0.xsd" name="http_client_extension" uuid="EA6A381D-2E78-448C-8A6D-B71759F1082E" library_target="http_client_extension">
|
||||
<target name="http_client_extension">
|
||||
<root all_classes="true"/>
|
||||
<option warning="true" void_safety="all">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<setting name="console_application" value="true"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension-safe.ecf"/>
|
||||
<library name="curl" location="$ISE_LIBRARY\library\cURL\cURL-safe.ecf"/>
|
||||
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/>
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="http_client" location="$ISE_LIBRARY\contrib\library\network\http_client\http_client-safe.ecf"/>
|
||||
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
|
||||
<library name="uri" location="$ISE_LIBRARY\library\text\uri\uri-safe.ecf"/>
|
||||
<cluster name="http_client_extension" location=".\src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
</target>
|
||||
</system>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-14-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-14-0 http://www.eiffel.com/developers/xml/configuration-1-14-0.xsd" name="http_client_extension" uuid="DD90A4FA-1B7F-4C8C-A739-AE67D6F40384" library_target="http_client_extension">
|
||||
<target name="http_client_extension">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" void_safety="none">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<setting name="console_application" value="true"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension.ecf"/>
|
||||
<library name="curl" location="$ISE_LIBRARY\library\cURL\cURL.ecf"/>
|
||||
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder.ecf"/>
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http.ecf"/>
|
||||
<library name="http_client" location="$ISE_LIBRARY\contrib\library\network\http_client\http_client.ecf"/>
|
||||
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
|
||||
<library name="uri" location="$ISE_LIBRARY\library\text\uri\uri.ecf"/>
|
||||
<cluster name="http_client_extension" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
@@ -0,0 +1,199 @@
|
||||
note
|
||||
description: "Represent an HTTP request."
|
||||
date: "$Date: 2015-10-08 07:51:29 -0300 (ju., 08 oct. 2015) $"
|
||||
revision: "$Revision: 97966 $"
|
||||
|
||||
class
|
||||
REQUEST
|
||||
|
||||
inherit
|
||||
|
||||
HTTP_CONSTANTS
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_method: READABLE_STRING_8; a_uri: READABLE_STRING_8)
|
||||
require
|
||||
valid_http_method: is_http_method (a_method)
|
||||
valid_uri: is_valid_uri (a_uri)
|
||||
do
|
||||
verb := a_method
|
||||
uri := a_uri
|
||||
create headers.make (5)
|
||||
ensure
|
||||
ver_set: verb = a_method
|
||||
uri_set: uri = a_uri
|
||||
end
|
||||
|
||||
feature -- Status Report
|
||||
|
||||
is_valid_uri (a_uri: READABLE_STRING_8): BOOLEAN
|
||||
local
|
||||
l_uri: URI
|
||||
do
|
||||
create l_uri.make_from_string (a_uri)
|
||||
Result := l_uri.is_valid
|
||||
end
|
||||
|
||||
query_string: detachable READABLE_STRING_8
|
||||
local
|
||||
l_uri: URI
|
||||
do
|
||||
create l_uri.make_from_string (uri)
|
||||
Result := l_uri.query
|
||||
end
|
||||
|
||||
sanitized_url: READABLE_STRING_8
|
||||
-- Returns the URL without the query string part
|
||||
local
|
||||
l_uri: URI
|
||||
do
|
||||
create l_uri.make_from_string (uri)
|
||||
l_uri.remove_query
|
||||
Result := l_uri.string
|
||||
ensure
|
||||
sanitized: not as_uri (Result).has_query
|
||||
end
|
||||
|
||||
is_http_method (a_method: READABLE_STRING_GENERAL): BOOLEAN
|
||||
do
|
||||
if a_method.same_string (method_connect) then
|
||||
Result := True
|
||||
elseif a_method.same_string (method_delete) then
|
||||
Result := True
|
||||
elseif a_method.same_string (method_get) then
|
||||
Result := True
|
||||
elseif a_method.same_string (method_head) then
|
||||
Result := True
|
||||
elseif a_method.same_string (method_options) then
|
||||
Result := True
|
||||
elseif a_method.same_string (method_patch) then
|
||||
Result := True
|
||||
elseif a_method.same_string (method_post) then
|
||||
Result := True
|
||||
elseif a_method.same_string (method_put) then
|
||||
Result := True
|
||||
elseif a_method.same_string (method_trace) then
|
||||
Result := True
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Constants
|
||||
|
||||
content_type_header_name: STRING_8 = "Content-Type";
|
||||
|
||||
default_content_type: STRING
|
||||
once
|
||||
Result := application_json
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
uri: READABLE_STRING_8
|
||||
|
||||
verb: READABLE_STRING_8
|
||||
|
||||
headers: STRING_TABLE [READABLE_STRING_8]
|
||||
|
||||
payload: detachable READABLE_STRING_8
|
||||
|
||||
executor: detachable REQUEST_EXECUTOR
|
||||
|
||||
feature -- Change Element
|
||||
|
||||
add_payload (a_payload: like payload)
|
||||
do
|
||||
payload := a_payload
|
||||
ensure
|
||||
payload_set: attached payload as l_payload implies l_payload = a_payload
|
||||
end
|
||||
|
||||
add_header (key: READABLE_STRING_8; value: READABLE_STRING_8)
|
||||
do
|
||||
headers.force (value, key)
|
||||
end
|
||||
|
||||
feature -- Execute
|
||||
|
||||
execute: detachable RESPONSE
|
||||
do
|
||||
initialize_executor
|
||||
Result := execute_request
|
||||
end
|
||||
|
||||
initialize_executor
|
||||
do
|
||||
create executor.make (uri, verb)
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
execute_request: detachable RESPONSE
|
||||
do
|
||||
if attached executor as l_executor then
|
||||
-- add headers
|
||||
add_headers (l_executor)
|
||||
if verb.same_string (method_put) or else verb.same_string (method_post) or else verb.same_string (method_patch) then
|
||||
l_executor.set_body (body_contents)
|
||||
end
|
||||
if not l_executor.context_executor.headers.has (content_type_header_name) then
|
||||
l_executor.context_executor.add_header (content_type_header_name, default_content_type)
|
||||
end
|
||||
if attached l_executor.execute as l_response then
|
||||
create Result.make (l_response)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
add_headers (a_executor: REQUEST_EXECUTOR)
|
||||
local
|
||||
l_context_executor: HTTP_CLIENT_REQUEST_CONTEXT
|
||||
s: READABLE_STRING_GENERAL
|
||||
utf: UTF_CONVERTER
|
||||
do
|
||||
l_context_executor := a_executor.context_executor
|
||||
across
|
||||
headers as ic
|
||||
loop
|
||||
s := ic.key
|
||||
if s.is_valid_as_string_8 then
|
||||
l_context_executor.add_header (s.as_string_8, ic.item)
|
||||
else
|
||||
l_context_executor.add_header (utf.utf_32_string_to_utf_8_string_8 (s), ic.item)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
body_contents: READABLE_STRING_8
|
||||
do
|
||||
if attached payload as l_payload then
|
||||
Result := l_payload
|
||||
else
|
||||
Result := ""
|
||||
end
|
||||
end
|
||||
|
||||
as_uri (a_string: READABLE_STRING_8): URI
|
||||
require
|
||||
is_valid_uri: is_valid_uri (a_string)
|
||||
do
|
||||
create Result.make_from_string (a_string)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015 Javier Velilla, 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
|
||||
]"
|
||||
|
||||
end
|
||||
@@ -0,0 +1,97 @@
|
||||
note
|
||||
description: "Executes an HTTP request"
|
||||
date: "$Date: 2015-10-08 07:51:29 -0300 (ju., 08 oct. 2015) $"
|
||||
revision: "$Revision: 97966 $"
|
||||
|
||||
class
|
||||
REQUEST_EXECUTOR
|
||||
|
||||
inherit
|
||||
|
||||
HTTP_CLIENT_HELPER
|
||||
|
||||
HTTP_CONSTANTS
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_url: READABLE_STRING_8; a_method: READABLE_STRING_8)
|
||||
do
|
||||
set_base_url (a_url)
|
||||
verb := a_method
|
||||
ensure
|
||||
base_url_set: base_url.same_string (a_url)
|
||||
method_set: verb.same_string (a_method)
|
||||
end
|
||||
|
||||
set_base_url (a_url: READABLE_STRING_8)
|
||||
-- Set base_url with `a_url'
|
||||
local
|
||||
s: STRING
|
||||
do
|
||||
create s.make_from_string (a_url)
|
||||
s.left_adjust
|
||||
s.right_adjust
|
||||
base_url := s
|
||||
ensure
|
||||
base_url_set: a_url.has_substring (base_url)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
verb: READABLE_STRING_8
|
||||
-- HTTP METHOD (Get, Post, ...)
|
||||
|
||||
body: detachable READABLE_STRING_8
|
||||
-- body content
|
||||
|
||||
feature -- Element Change
|
||||
|
||||
set_body (a_body: like body)
|
||||
-- Set body with `a_body'.
|
||||
do
|
||||
body := a_body
|
||||
ensure
|
||||
body_set: body = a_body
|
||||
end
|
||||
|
||||
feature -- Execute
|
||||
|
||||
execute: detachable HTTP_CLIENT_RESPONSE
|
||||
-- Http executor
|
||||
do
|
||||
if verb.same_string (method_connect) then
|
||||
Result := Void -- not supported for now
|
||||
elseif verb.same_string (method_delete) then
|
||||
Result := execute_delete ("")
|
||||
elseif verb.same_string (method_get) then
|
||||
Result := execute_get ("")
|
||||
elseif verb.same_string (method_head) then
|
||||
Result := Void
|
||||
elseif verb.same_string (method_options) then
|
||||
Result := Void
|
||||
elseif verb.same_string (method_patch) then
|
||||
Result := execute_patch ("", body)
|
||||
elseif verb.same_string (method_post) then
|
||||
Result := execute_post ("", body)
|
||||
elseif verb.same_string (method_put) then
|
||||
Result := execute_put ("", body)
|
||||
elseif verb.same_string (method_trace) then
|
||||
Result := Void
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015 Javier Velilla, 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
|
||||
]"
|
||||
|
||||
end
|
||||
@@ -0,0 +1,57 @@
|
||||
note
|
||||
description: "Represent and HTTP Response"
|
||||
date: "$Date: 2015-10-08 07:51:29 -0300 (ju., 08 oct. 2015) $"
|
||||
revision: "$Revision: 97966 $"
|
||||
|
||||
class
|
||||
RESPONSE
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} --Initialization
|
||||
|
||||
make (a_response: HTTP_CLIENT_RESPONSE)
|
||||
do
|
||||
http_response := a_response
|
||||
body := a_response.body
|
||||
status := a_response.status
|
||||
headers := a_response.headers
|
||||
status_message := a_response.status_line
|
||||
error_message := a_response.error_message
|
||||
ensure
|
||||
http_reponse_set: http_response = a_response
|
||||
headers_set: headers = a_response.headers
|
||||
status_set: status = a_response.status
|
||||
status_message_set: status_message = a_response.status_line
|
||||
error_message_set: error_message = a_response.error_message
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
status: INTEGER
|
||||
|
||||
status_message: detachable READABLE_STRING_8
|
||||
|
||||
error_message: detachable READABLE_STRING_8
|
||||
|
||||
body: detachable READABLE_STRING_8
|
||||
|
||||
headers: LIST [TUPLE [name: READABLE_STRING_8; value: READABLE_STRING_8]]
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
http_response: HTTP_CLIENT_RESPONSE;
|
||||
|
||||
note
|
||||
copyright: "2011-2015 Javier Velilla, 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
|
||||
]"
|
||||
|
||||
end
|
||||
@@ -0,0 +1,99 @@
|
||||
note
|
||||
description: "Wrapper class for HTTP_CLIENT_SESSION"
|
||||
date: "$Date: 2015-10-08 07:51:29 -0300 (ju., 08 oct. 2015) $"
|
||||
revision: "$Revision: 97966 $"
|
||||
|
||||
deferred class
|
||||
HTTP_CLIENT_HELPER
|
||||
|
||||
feature -- Access
|
||||
|
||||
http_session: detachable HTTP_CLIENT_SESSION
|
||||
|
||||
get_http_session
|
||||
local
|
||||
h: LIBCURL_HTTP_CLIENT
|
||||
b: like base_url
|
||||
do
|
||||
create h.make
|
||||
b := base_url
|
||||
if b = Void then
|
||||
b := ""
|
||||
end
|
||||
if attached {HTTP_CLIENT_SESSION} h.new_session (base_url) as sess then
|
||||
http_session := sess
|
||||
sess.set_timeout (-1)
|
||||
sess.set_connect_timeout (-1)
|
||||
sess.set_is_insecure (True)
|
||||
sess.set_any_auth_type
|
||||
debug ("curl")
|
||||
sess.set_is_debug (True)
|
||||
end
|
||||
debug ("proxy8888")
|
||||
sess.set_proxy ("127.0.0.1", 8888) --| inspect traffic with http://www.fiddler2.com/
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- HTTP client helpers
|
||||
|
||||
execute_get (command_name: READABLE_STRING_8): detachable HTTP_CLIENT_RESPONSE
|
||||
do
|
||||
get_http_session
|
||||
if attached http_session as sess then
|
||||
Result := sess.get (command_name, context_executor)
|
||||
end
|
||||
end
|
||||
|
||||
execute_post (command_name: READABLE_STRING_8; data: detachable READABLE_STRING_8): detachable HTTP_CLIENT_RESPONSE
|
||||
do
|
||||
get_http_session
|
||||
if attached http_session as sess then
|
||||
Result := sess.post (command_name, context_executor, data)
|
||||
end
|
||||
end
|
||||
|
||||
execute_delete (command_name: READABLE_STRING_8): detachable HTTP_CLIENT_RESPONSE
|
||||
do
|
||||
get_http_session
|
||||
if attached http_session as sess then
|
||||
Result := sess.delete (command_name, context_executor)
|
||||
end
|
||||
end
|
||||
|
||||
execute_put (command_name: READABLE_STRING_8; data: detachable READABLE_STRING_8): detachable HTTP_CLIENT_RESPONSE
|
||||
do
|
||||
get_http_session
|
||||
if attached http_session as sess then
|
||||
Result := sess.put (command_name, context_executor, data)
|
||||
end
|
||||
end
|
||||
|
||||
execute_patch (command_name: READABLE_STRING_8; data: detachable READABLE_STRING_8): detachable HTTP_CLIENT_RESPONSE
|
||||
do
|
||||
get_http_session
|
||||
if attached http_session as sess then
|
||||
Result := sess.patch (command_name, context_executor, data)
|
||||
end
|
||||
end
|
||||
|
||||
context_executor: HTTP_CLIENT_REQUEST_CONTEXT
|
||||
-- request context for each request
|
||||
once
|
||||
create Result.make
|
||||
end
|
||||
|
||||
base_url: STRING;
|
||||
|
||||
note
|
||||
copyright: "2011-2015 Javier Velilla, 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
|
||||
]"
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user