From 0557d1ee2dfc826631739bfa31b7a14be64cb0c2 Mon Sep 17 00:00:00 2001 From: Florian Jacky Date: Wed, 19 Aug 2015 22:50:11 +0200 Subject: [PATCH] added remaining features --- .../src/spec/socket/net_http_client_request.e | 125 ++++++++++++---- .../src/spec/socket/net_http_client_session.e | 1 + .../network/http_client/tests/application.e | 137 ++++++++++++++++++ .../network/http_client/tests/httptest.ecf | 20 +++ 4 files changed, 258 insertions(+), 25 deletions(-) create mode 100644 library/network/http_client/tests/application.e create mode 100644 library/network/http_client/tests/httptest.ecf diff --git a/library/network/http_client/src/spec/socket/net_http_client_request.e b/library/network/http_client/src/spec/socket/net_http_client_request.e index 14f0b71f..5683b0e8 100644 --- a/library/network/http_client/src/spec/socket/net_http_client_request.e +++ b/library/network/http_client/src/spec/socket/net_http_client_request.e @@ -47,14 +47,21 @@ feature -- Access l_platform: STRING l_useragent: STRING l_upload_data: detachable READABLE_STRING_8 + l_form_data: detachable HASH_TABLE [READABLE_STRING_32, READABLE_STRING_32] ctx: like context - l_has_content: BOOLEAN l_upload_file: detachable RAW_FILE l_upload_filename: detachable READABLE_STRING_GENERAL + l_form_string: STRING + l_mime_type_mapping: HTTP_FILE_EXTENSION_MIME_MAPPING + l_mime_type: STRING + l_fn_extension: READABLE_STRING_GENERAL + l_i: INTEGER do ctx := context create Result.make (url) + create l_form_string.make_empty + -- Get URL data create l_uri.make_from_string (url) l_port := l_uri.port @@ -81,6 +88,7 @@ feature -- Access if attached l_authorization.http_authorization as auth then headers.extend (auth, "Authorization") end + check headers.has_key ("Authorization") end end end end @@ -106,6 +114,7 @@ feature -- Access headers.extend (l_useragent, "User-Agent") end + -- handle sending data if attached ctx then if ctx.has_upload_filename then @@ -116,44 +125,110 @@ feature -- Access l_upload_data := ctx.upload_data end - -- handle post requests - if request_method.is_case_insensitive_equal ("POST") then - if ctx /= Void then - if ctx.has_upload_data then - l_upload_data := ctx.upload_data - if l_upload_data /= Void then - headers.extend ("application/x-www-form-urlencoded", "Content-Type") - headers.extend (l_upload_data.count.out, "Content-Length") + if ctx.has_form_data then + l_form_data := ctx.form_parameters + check non_empty_form_data: not l_form_data.is_empty end + if l_upload_data = Void and l_upload_filename = Void then + -- Send as form-urlencoded + headers.extend ("application/x-www-form-urlencoded", "Content-Type") + l_upload_data := ctx.form_parameters_to_url_encoded_string + headers.extend (l_upload_data.count.out, "Content-Length") + + else + -- create form + headers.extend ("multipart/form-data; boundary=----------------------------5eadfcf3bb3e", "Content-Type") + if attached l_form_data then + headers.extend ("*/*", "Accept") + from + l_form_data.start + until + l_form_data.after + loop + l_form_string.append ("------------------------------5eadfcf3bb3e") + l_form_string.append (http_end_of_header_line) + l_form_string.append ("Content-Disposition: form-data; name=") + l_form_string.append ("%"" + l_form_data.key_for_iteration + "%"") + l_form_string.append (http_end_of_header_line) + l_form_string.append (http_end_of_header_line) + l_form_string.append (l_form_data.item_for_iteration) + l_form_string.append (http_end_of_header_line) + l_form_data.forth end - elseif ctx.has_upload_filename then - if l_upload_filename /= Void then + + if l_upload_filename /= Void then + -- get file extension, otherwise set default + l_mime_type := "application/octet-stream" + create l_mime_type_mapping.make_default + l_fn_extension := l_upload_filename.tail (l_upload_filename.count - l_upload_filename.last_index_of ('.', l_upload_filename.count)) + if attached l_mime_type_mapping.mime_type (l_fn_extension) as mime then + l_mime_type := mime + end + + l_form_string.append ("------------------------------5eadfcf3bb3e") + l_form_string.append (http_end_of_header_line) + l_form_string.append ("Content-Disposition: form-data; name=%"" + l_upload_filename.as_string_32 + "%"") + l_form_string.append ("; filename=%"" + l_upload_filename + "%"") + l_form_string.append (http_end_of_header_line) + l_form_string.append ("Content-Type: ") + l_form_string.append (l_mime_type) + l_form_string.append (http_end_of_header_line) + l_form_string.append (http_end_of_header_line) + create l_upload_file.make_with_name (l_upload_filename) if l_upload_file.exists and then l_upload_file.is_readable then - headers.extend (l_upload_file.count.out, "Content-Length") l_upload_file.open_read + l_upload_file.read_stream (l_upload_file.count) + l_form_string.append (l_upload_file.last_string) + end + l_form_string.append (http_end_of_header_line) + end + l_form_string.append ("------------------------------5eadfcf3bb3e--") + + l_upload_data := l_form_string + headers.extend (l_upload_data.count.out, "Content-Length") + end + end + else + if request_method.is_case_insensitive_equal ("POST") then + if ctx /= Void then + if ctx.has_upload_data then + l_upload_data := ctx.upload_data + if l_upload_data /= Void then + headers.extend ("application/x-www-form-urlencoded", "Content-Type") + headers.extend (l_upload_data.count.out, "Content-Length") + end + elseif ctx.has_upload_filename then + if l_upload_filename /= Void then + create l_upload_file.make_with_name (l_upload_filename) + if l_upload_file.exists and then l_upload_file.is_readable then + headers.extend (l_upload_file.count.out, "Content-Length") + l_upload_file.open_read + end + check l_upload_file /= Void end end end end end end + end - -- handle put requests - if request_method.is_case_insensitive_equal ("PUT") then - if ctx /= Void then - if ctx.has_upload_filename then - if l_upload_filename /= Void then - create l_upload_file.make_with_name (l_upload_filename) - if l_upload_file.exists and then l_upload_file.is_readable then - headers.extend (l_upload_file.count.out, "Content-Length") - l_upload_file.open_read - end + -- handle put requests + if request_method.is_case_insensitive_equal ("PUT") then + if ctx /= Void then + if ctx.has_upload_filename then + if l_upload_filename /= Void then + create l_upload_file.make_with_name (l_upload_filename) + if l_upload_file.exists and then l_upload_file.is_readable then + headers.extend (l_upload_file.count.out, "Content-Length") + l_upload_file.open_read end - + check l_upload_filename /= Void end end + end - - end + + end -- Connect diff --git a/library/network/http_client/src/spec/socket/net_http_client_session.e b/library/network/http_client/src/spec/socket/net_http_client_session.e index e6d8a318..0e1fd2cb 100644 --- a/library/network/http_client/src/spec/socket/net_http_client_session.e +++ b/library/network/http_client/src/spec/socket/net_http_client_session.e @@ -140,6 +140,7 @@ feature {NONE} -- Implementation --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) diff --git a/library/network/http_client/tests/application.e b/library/network/http_client/tests/application.e new file mode 100644 index 00000000..f3486044 --- /dev/null +++ b/library/network/http_client/tests/application.e @@ -0,0 +1,137 @@ +note + description : "httptest application root class" + date : "$Date$" + revision : "$Revision$" + +class + APPLICATION + +inherit + ARGUMENTS + +create + make + +feature {NONE} -- Initialization + + make + -- Run application. + local + sess: NET_HTTP_CLIENT_SESSION + h: STRING_8 + l_ctx: HTTP_CLIENT_REQUEST_CONTEXT + l_test_case: INTEGER + l_requestbin_path: STRING + do + l_requestbin_path := "/15u47xi2" + create h.make_empty + + l_test_case := 1 -- select which test to execute + + inspect l_test_case + when 1 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 sess.make("http://requestb.in") + if attached sess.post (l_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) + when 2 then + -- 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") + if attached sess.post (l_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 + + when 3 then + -- 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") + if attached sess.post (l_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 + + when 4 then + -- 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") + if attached sess.put (l_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 + + when 5 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 + 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") + if attached sess.post (l_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 + + when 6 then + -- GET REQUEST, Forwarding (google's first answer is a forward) + -- check headers received (printed in console) + create sess.make("http://google.com") + 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) + + when 7 then + -- GET REQUEST WITH AUTHENTICATION, see http://browserspy.dk/password.php + -- check header WWW-Authendicate is received (authentication successful) + create sess.make("http://test:test1@browserspy.dk") + 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) + else + end + end + +end diff --git a/library/network/http_client/tests/httptest.ecf b/library/network/http_client/tests/httptest.ecf new file mode 100644 index 00000000..bf9c2e6e --- /dev/null +++ b/library/network/http_client/tests/httptest.ecf @@ -0,0 +1,20 @@ + + + + + + + + + + + + /EIFGENs$ + /CVS$ + /.svn$ + + + +