Added null http client for upcoming changes.

Refactored NET request implementation.
  - fixed potential issue with header conflict.
  - simplified, and extract parts of the code into routine.
  - Implemented read of chunked Transfer-Encoding
  - Fixed potential issue with socket handling.
First steps to be able to exclude net or libcurl implementation when using http_client lib.
Removed from NET implementation the hack related to PUT and upload data (it was used to workaround an issue with libcurl).
This commit is contained in:
2015-09-14 21:34:37 +02:00
parent 29c4931dc0
commit eec3cbdba1
18 changed files with 1131 additions and 570 deletions

View File

@@ -1,190 +0,0 @@
note
description : "httptest application root class"
date : "$Date$"
revision : "$Revision$"
class
APPLICATION
inherit
ARGUMENTS
create
make
feature {NONE} -- Initialization
make
-- Run application.
do
requestbin_path := "/15u47xi2"
test_1
test_2
test_3
test_4
test_5
test_6
test_7
end
requestbin_path: STRING
feature -- Tests
test_1
local
sess: NET_HTTP_CLIENT_SESSION
h: STRING_8
l_ctx: HTTP_CLIENT_REQUEST_CONTEXT
do
-- URL ENCODED POST REQUEST
-- check requestbin to ensure the "Hello World" has been received in the raw body
-- also check that User-Agent was sent
create h.make_empty
create sess.make("http://requestb.in")
if attached sess.post (requestbin_path, Void, "Hello World").headers as hds then
across
hds as c
loop
h.append (c.item.name + ": " + c.item.value + "%R%N")
end
end
print (h)
end
test_2
local
sess: NET_HTTP_CLIENT_SESSION
h: STRING_8
l_ctx: HTTP_CLIENT_REQUEST_CONTEXT
do
-- POST REQUEST WITH FORM DATA
-- check requestbin to ensure the form parameters are correctly received
create sess.make("http://requestb.in")
create l_ctx.make
l_ctx.form_parameters.extend ("First Value", "First Key")
l_ctx.form_parameters.extend ("Second Value", "Second Key")
create sess.make("http://requestb.in")
create h.make_empty
if attached sess.post (requestbin_path, l_ctx, "").headers as hds then
across
hds as c
loop
h.append (c.item.name + ": " + c.item.value + "%R%N")
end
end
print (h)
end
test_3
local
sess: NET_HTTP_CLIENT_SESSION
h: STRING_8
l_ctx: HTTP_CLIENT_REQUEST_CONTEXT
do
-- POST REQUEST WITH A FILE
-- check requestbin to ensure the form parameters are correctly received
-- set filename to a local file
create sess.make("http://requestb.in")
create l_ctx.make
l_ctx.set_upload_filename ("C:\temp\test.txt")
create h.make_empty
if attached sess.post (requestbin_path, l_ctx, "").headers as hds then
across
hds as c
loop
h.append (c.item.name + ": " + c.item.value + "%R%N")
end
end
print (h)
end
test_4
local
sess: NET_HTTP_CLIENT_SESSION
h: STRING_8
l_ctx: HTTP_CLIENT_REQUEST_CONTEXT
do
-- PUT REQUEST WITH A FILE
-- check requestbin to ensure the file is correctly received
-- set filename to a local file
create sess.make("http://requestb.in")
create l_ctx.make
l_ctx.set_upload_filename ("C:\temp\test.txt")
create h.make_empty
if attached sess.put (requestbin_path, l_ctx, "").headers as hds then
across
hds as c
loop
h.append (c.item.name + ": " + c.item.value + "%R%N")
end
end
print (h)
end
test_5
local
sess: NET_HTTP_CLIENT_SESSION
h: STRING_8
l_ctx: HTTP_CLIENT_REQUEST_CONTEXT
do
-- POST REQUEST WITH A FILE AND FORM DATA
-- check requestbin to ensure the file and form parameters are correctly received
-- set filename to a local file
create sess.make("http://requestb.in")
create l_ctx.make
l_ctx.set_upload_filename ("C:\temp\logo.png")
l_ctx.form_parameters.extend ("First Value", "First Key")
l_ctx.form_parameters.extend ("Second Value", "Second Key")
create h.make_empty
if attached sess.post (requestbin_path, l_ctx, "").headers as hds then
across
hds as c
loop
h.append (c.item.name + ": " + c.item.value + "%R%N")
end
end
print (h)
end
test_6
local
sess: NET_HTTP_CLIENT_SESSION
h: STRING_8
l_ctx: HTTP_CLIENT_REQUEST_CONTEXT
do
-- GET REQUEST, Forwarding (google's first answer is a forward)
-- check headers received (printed in console)
create sess.make("http://google.com")
create h.make_empty
if attached sess.get ("/", Void).headers as hds then
across
hds as c
loop
h.append (c.item.name + ": " + c.item.value + "%R%N")
end
end
print (h)
end
test_7
local
sess: NET_HTTP_CLIENT_SESSION
h: STRING_8
l_ctx: HTTP_CLIENT_REQUEST_CONTEXT
do
-- GET REQUEST WITH AUTHENTICATION, see http://browserspy.dk/password.php
-- check header WWW-Authenticate is received (authentication successful)
create sess.make("http://test:test@browserspy.dk")
create h.make_empty
if attached sess.get ("/password-ok.php", Void).headers as hds then
across
hds as c
loop
h.append (c.item.name + ": " + c.item.value + "%R%N")
end
end
print (h)
end
end

View File

@@ -1,19 +0,0 @@
<?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="httptest" uuid="C8DFC1BA-78CA-4518-B0F2-2241E42808FF">
<target name="httptest">
<root class="APPLICATION" feature="make"/>
<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="http_client" location="..\http_client-safe.ecf"/>
<cluster name="httptest" location=".\" recursive="true">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
</cluster>
</target>
</system>

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

@@ -6,7 +6,13 @@ create
feature -- Init
make
local
null: NULL_HTTP_CLIENT
do
create null
if attached null.new_session ("http://example.com/") as l_sess then
check not l_sess.is_available end
end
test_http_client
end
@@ -42,7 +48,7 @@ feature -- Init
do
if not b then
create e
e.set_message (m)
e.set_description (m)
e.raise
end
end

View File

@@ -0,0 +1 @@
This is a text sample for testing HTTP Client library.

View File

@@ -44,8 +44,6 @@ feature -- Test routines
assert ("missing body", False)
end
assert ("same headers", h.same_string (res.raw_header))
else
assert ("Not found", False)
end
end
@@ -54,7 +52,6 @@ feature -- Test routines
sess: like new_session
h: STRING_8
do
--| Add your code here
sess := new_session ("http://requestb.in")
create h.make_empty
if attached sess.get ("/1a0q2h61", Void).headers as hds then
@@ -64,7 +61,6 @@ feature -- Test routines
h.append (c.item.name + ": " + c.item.value + "%R%N")
end
end
print (h)
end

View File

@@ -0,0 +1,67 @@
note
description: "[
Objects that ...
]"
author: "$Author$"
date: "$Date$"
revision: "$Revision$"
class
TEST_LIBCURL_WITH_WEB
inherit
TEST_WITH_WEB_I
feature -- Factory
new_session (a_url: READABLE_STRING_8): HTTP_CLIENT_SESSION
local
cl: LIBCURL_HTTP_CLIENT
do
create cl
Result := cl.new_session (a_url)
end
feature -- Tests
libcurl_test_post_url_encoded
do
test_post_url_encoded
end
libcurl_test_post_with_form_data
do
test_post_with_form_data
end
libcurl_test_post_with_file
do
test_post_with_file
end
libcurl_test_put_with_file
do
test_put_with_file
end
libcurl_test_put_with_data
do
test_put_with_data
end
libcurl_test_post_with_file_and_form_data
do
test_post_with_file_and_form_data
end
libcurl_test_get_with_redirection
do
test_get_with_redirection
end
libcurl_test_get_with_authentication
do
test_get_with_authentication
end
end

View File

@@ -0,0 +1,67 @@
note
description: "[
Objects that ...
]"
author: "$Author$"
date: "$Date$"
revision: "$Revision$"
class
TEST_NET_WITH_WEB
inherit
TEST_WITH_WEB_I
feature -- Factory
new_session (a_url: READABLE_STRING_8): HTTP_CLIENT_SESSION
local
cl: NET_HTTP_CLIENT
do
create cl
Result := cl.new_session (a_url)
end
feature -- Tests
net_test_post_url_encoded
do
test_post_url_encoded
end
net_test_post_with_form_data
do
test_post_with_form_data
end
net_test_post_with_file
do
test_post_with_file
end
net_test_put_with_file
do
test_put_with_file
end
net_test_put_with_data
do
test_put_with_data
end
net_test_post_with_file_and_form_data
do
test_post_with_file_and_form_data
end
net_test_get_with_redirection
do
test_get_with_redirection
end
net_test_get_with_authentication
do
test_get_with_authentication
end
end

View File

@@ -0,0 +1,302 @@
note
description: "[
Eiffel tests that can be executed by testing tool.
]"
author: "EiffelStudio test wizard"
date: "$Date$"
revision: "$Revision$"
testing: "type/manual"
deferred class
TEST_WITH_WEB_I
inherit
EQA_TEST_SET
redefine
on_prepare
end
feature -- Initialization
on_prepare
do
Precursor
global_requestbin_path := new_requestbin_path
end
feature -- Factory
new_session (a_url: READABLE_STRING_8): HTTP_CLIENT_SESSION
deferred
end
feature -- Requestbin
global_requestbin_path: detachable READABLE_STRING_8
new_requestbin_path: detachable STRING
local
i,j: INTEGER
do
if
attached new_session ("http://requestb.in") as sess and then
attached sess.post ("/api/v1/bins", Void, Void) as resp
then
if resp.error_occurred then
print ("Error occurred!%N")
elseif attached resp.body as l_content then
i := l_content.substring_index ("%"name%":", 1)
if i > 0 then
j := l_content.index_of (',', i + 1)
if j > 0 then
Result := l_content.substring (i + 7, j - 1)
Result.adjust
if Result.starts_with ("%"") then
Result.remove_head (1)
end
if Result.ends_with ("%"") then
Result.remove_tail (1)
end
if not Result.starts_with ("/") then
Result.prepend_character ('/')
end
end
end
end
end
end
feature -- Factory
test_post_url_encoded
local
sess: HTTP_CLIENT_SESSION
h: STRING_8
do
if attached global_requestbin_path as requestbin_path then
-- URL ENCODED POST REQUEST
-- check requestbin to ensure the "Hello World" has been received in the raw body
-- also check that User-Agent was sent
create h.make_empty
sess := new_session ("http://requestb.in")
if
attached sess.post (requestbin_path, Void, "Hello World") as res and then
attached res.headers as hds
then
across
hds as c
loop
h.append (c.item.name + ": " + c.item.value + "%R%N")
end
end
print (h)
else
assert ("Has requestbin path", False)
end
end
test_post_with_form_data
local
sess: HTTP_CLIENT_SESSION
h: STRING_8
l_ctx: HTTP_CLIENT_REQUEST_CONTEXT
do
if attached global_requestbin_path as requestbin_path then
-- POST REQUEST WITH FORM DATA
-- check requestbin to ensure the form parameters are correctly received
sess := new_session ("http://requestb.in")
create l_ctx.make
l_ctx.form_parameters.extend ("First Value", "First Key")
l_ctx.form_parameters.extend ("Second Value", "Second Key")
create h.make_empty
if
attached sess.post (requestbin_path, l_ctx, "") as res and then
attached res.headers as hds
then
across
hds as c
loop
h.append (c.item.name + ": " + c.item.value + "%R%N")
end
end
print (h)
else
assert ("Has requestbin path", False)
end
end
test_post_with_file
local
sess: HTTP_CLIENT_SESSION
h: STRING_8
l_ctx: HTTP_CLIENT_REQUEST_CONTEXT
do
if attached global_requestbin_path as requestbin_path then
-- POST REQUEST WITH A FILE
-- check requestbin to ensure the form parameters are correctly received
-- set filename to a local file
sess := new_session ("http://requestb.in")
create l_ctx.make
l_ctx.set_upload_filename ("test.txt")
create h.make_empty
if
attached sess.post (requestbin_path, l_ctx, "") as res and then
attached res.headers as hds
then
across
hds as c
loop
h.append (c.item.name + ": " + c.item.value + "%R%N")
end
end
print (h)
else
assert ("Has requestbin path", False)
end
end
test_put_with_file
local
sess: HTTP_CLIENT_SESSION
h: STRING_8
l_ctx: HTTP_CLIENT_REQUEST_CONTEXT
do
if attached global_requestbin_path as requestbin_path then
-- PUT REQUEST WITH A FILE
-- check requestbin to ensure the file is correctly received
-- set filename to a local file
sess := new_session ("http://requestb.in")
create l_ctx.make
l_ctx.set_upload_filename ("test.txt")
create h.make_empty
if
attached sess.put (requestbin_path, l_ctx, Void) as res and then
attached res.headers as hds
then
across
hds as c
loop
h.append (c.item.name + ": " + c.item.value + "%R%N")
end
end
print (h)
else
assert ("Has requestbin path", False)
end
end
test_put_with_data
local
sess: HTTP_CLIENT_SESSION
h: STRING_8
l_ctx: HTTP_CLIENT_REQUEST_CONTEXT
do
if attached global_requestbin_path as requestbin_path then
-- PUT REQUEST WITH A FILE
-- check requestbin to ensure the file is correctly received
-- set filename to a local file
sess := new_session ("http://requestb.in")
create l_ctx.make
l_ctx.set_upload_data ("This is a test for http client.%N")
create h.make_empty
if
attached sess.put (requestbin_path, l_ctx, Void) as res and then
attached res.headers as hds
then
across
hds as c
loop
h.append (c.item.name + ": " + c.item.value + "%R%N")
end
end
print (h)
else
assert ("Has requestbin path", False)
end
end
test_post_with_file_and_form_data
local
sess: HTTP_CLIENT_SESSION
h: STRING_8
l_ctx: HTTP_CLIENT_REQUEST_CONTEXT
do
if attached global_requestbin_path as requestbin_path then
-- POST REQUEST WITH A FILE AND FORM DATA
-- check requestbin to ensure the file and form parameters are correctly received
-- set filename to a local file
sess := new_session ("http://requestb.in")
create l_ctx.make
l_ctx.set_upload_filename ("logo.jpg")
l_ctx.form_parameters.extend ("First Value", "First Key")
l_ctx.form_parameters.extend ("Second Value", "Second Key")
create h.make_empty
if
attached sess.post (requestbin_path, l_ctx, Void) as res and then
attached res.headers as hds
then
across
hds as c
loop
h.append (c.item.name + ": " + c.item.value + "%R%N")
end
end
print (h)
else
assert ("Has requestbin path", False)
end
end
test_get_with_redirection
local
sess: HTTP_CLIENT_SESSION
h: STRING_8
do
if attached global_requestbin_path as requestbin_path then
-- GET REQUEST, Forwarding (google's first answer is a forward)
-- check headers received (printed in console)
sess := new_session ("http://google.com")
create h.make_empty
if attached sess.get ("/", Void) as res and then attached res.headers as hds then
across
hds as c
loop
h.append (c.item.name + ": " + c.item.value + "%R%N")
end
end
print (h)
else
assert ("Has requestbin path", False)
end
end
test_get_with_authentication
local
sess: HTTP_CLIENT_SESSION
ctx: HTTP_CLIENT_REQUEST_CONTEXT
do
-- GET REQUEST WITH AUTHENTICATION, see http://browserspy.dk/password.php
-- check header WWW-Authenticate is received (authentication successful)
sess := new_session ("http://browserspy.dk")
sess.set_credentials ("test", "test")
create ctx.make_with_credentials_required
if attached sess.get ("/password-ok.php", ctx) as res then
if attached {READABLE_STRING_8} res.body as l_body then
assert ("Fetch all body, including closing html tag", l_body.has_substring ("</html>"))
else
assert ("has body", False)
end
end
end
end