From 6c7637716b5683761015336f4b36bd1125a53387 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Tue, 15 Sep 2015 23:45:41 +0200 Subject: [PATCH] Updated a few comments Removed useless NULL_HTTP_CLIENT. Extracted mime code from NET_HTTP_CLIENT_REQUEST.response into specific routine. --- .../network/http_client/http_client-safe.ecf | 2 + library/network/http_client/http_client.ecf | 45 ++- .../libcurl_or_net/default_http_client.e | 5 +- .../src/default/null/default_http_client.e | 20 +- .../http_client/src/http_client_request.e | 23 +- .../http_client/src/http_client_response.e | 8 + .../http_client/src/http_client_session.e | 8 +- .../libcurl/libcurl_http_client_session.e | 12 + .../src/spec/net/net_http_client_request.e | 292 ++++++++++-------- .../src/spec/net/net_http_client_session.e | 12 + .../src/spec/null/null_http_client.e | 33 -- .../src/spec/null/null_http_client_session.e | 8 +- .../network/http_client/tests/test-safe.ecf | 1 + library/network/http_client/tests/test.e | 9 +- 14 files changed, 294 insertions(+), 184 deletions(-) delete mode 100644 library/network/http_client/src/spec/null/null_http_client.e diff --git a/library/network/http_client/http_client-safe.ecf b/library/network/http_client/http_client-safe.ecf index d09ef84b..e00d349c 100644 --- a/library/network/http_client/http_client-safe.ecf +++ b/library/network/http_client/http_client-safe.ecf @@ -40,11 +40,13 @@ + + diff --git a/library/network/http_client/http_client.ecf b/library/network/http_client/http_client.ecf index 2e08d08f..3ab591ce 100644 --- a/library/network/http_client/http_client.ecf +++ b/library/network/http_client/http_client.ecf @@ -24,20 +24,63 @@ + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/network/http_client/src/default/libcurl_or_net/default_http_client.e b/library/network/http_client/src/default/libcurl_or_net/default_http_client.e index 9f50c575..e73d03df 100644 --- a/library/network/http_client/src/default/libcurl_or_net/default_http_client.e +++ b/library/network/http_client/src/default/libcurl_or_net/default_http_client.e @@ -1,6 +1,9 @@ note description: "[ - Default HTTP_CLIENT based on LIBCURL_HTTP_CLIENT. + Default HTTP_CLIENT based on LIBCURL_HTTP_CLIENT or NET_HTTP_CLIENT. + + The preference goes to libcurl implementation for now, + since the net implementation has currently less functionalities. ]" author: "$Author$" date: "$Date$" diff --git a/library/network/http_client/src/default/null/default_http_client.e b/library/network/http_client/src/default/null/default_http_client.e index 70b4a992..40edd11a 100644 --- a/library/network/http_client/src/default/null/default_http_client.e +++ b/library/network/http_client/src/default/null/default_http_client.e @@ -10,6 +10,24 @@ class DEFAULT_HTTP_CLIENT inherit - NULL_HTTP_CLIENT + HTTP_CLIENT +feature -- Access + + new_session (a_base_url: READABLE_STRING_8): HTTP_CLIENT_SESSION + -- Create a new session using `a_base_url'. + do + create {NULL_HTTP_CLIENT_SESSION} 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 diff --git a/library/network/http_client/src/http_client_request.e b/library/network/http_client/src/http_client_request.e index 5039b7fb..b11d1f15 100644 --- a/library/network/http_client/src/http_client_request.e +++ b/library/network/http_client/src/http_client_request.e @@ -15,9 +15,9 @@ inherit feature {NONE} -- Initialization make (a_url: READABLE_STRING_8; a_request_method: like request_method; a_session: like session; ctx: like context) - -- Initialize `Current'. + -- Initialize `Current' with request url `a_url', method `a_request_method' within the session `a_session' + -- and optional context `ctx' which can be used to pass additional parameters. do - current_redirects := 0 request_method := a_request_method session := a_session initialize (a_url, ctx) @@ -27,6 +27,9 @@ feature {NONE} -- Initialization end initialize (a_url: READABLE_STRING_8; ctx: like context) + -- Initialize Current with `a_url' and `ctx'. + -- This can be used to reset/reinitialize Current with new url + -- in the case of redirection. do url := a_url headers := session.headers.twin @@ -41,10 +44,11 @@ feature {NONE} -- Initialization feature {NONE} -- Internal session: HTTP_CLIENT_SESSION + -- Session related to Current request. + -- It provides a few parameters related to session. context: detachable HTTP_CLIENT_REQUEST_CONTEXT - - current_redirects: INTEGER_32 + -- Potential additional parameters for this specific request. feature -- Status report @@ -60,11 +64,14 @@ feature -- Access -- Request method associated with Current request. url: READABLE_STRING_8 + -- URL associated with current request. headers: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8] + -- Specific headers to be used for current request. response: HTTP_CLIENT_RESPONSE - -- Execute the request and return the response. + -- Response received from request execution. + -- Check `error_occurred' for eventual error. -- note: two consecutive calls will trigger two executions! deferred ensure @@ -74,6 +81,7 @@ feature -- Access feature {HTTP_CLIENT_SESSION} -- Execution import (ctx: HTTP_CLIENT_REQUEST_CONTEXT) + -- Import `ctx' parameters. local l_headers: like headers do @@ -104,21 +112,26 @@ feature -- Authentication end username: detachable READABLE_STRING_32 + -- Username specified for the `session'. do Result := session.username end password: detachable READABLE_STRING_32 + -- Password specified for the `session'. do Result := session.password end credentials: detachable READABLE_STRING_32 + -- Credentials specified for the `session'. + --| Usually `username':`password' do Result := session.credentials end proxy: detachable TUPLE [host: READABLE_STRING_8; port: INTEGER] + -- Optional proxy settings. do Result := session.proxy end diff --git a/library/network/http_client/src/http_client_response.e b/library/network/http_client/src/http_client_response.e index 92e64fe0..fe9c7cd4 100644 --- a/library/network/http_client/src/http_client_response.e +++ b/library/network/http_client/src/http_client_response.e @@ -63,6 +63,14 @@ feature -- Access redirections: detachable ARRAYED_LIST [TUPLE [status_line: detachable READABLE_STRING_8; raw_header: READABLE_STRING_8; body: detachable READABLE_STRING_8]] -- Header of previous redirection if any. + redirections_count: INTEGER + -- Number of redirections. + do + if attached redirections as lst then + Result := lst.count + end + end + header (a_name: READABLE_STRING_8): detachable READABLE_STRING_8 -- Header entry value related to `a_name' -- if multiple entries, just concatenate them using comma character diff --git a/library/network/http_client/src/http_client_session.e b/library/network/http_client/src/http_client_session.e index 9f9d5ded..e2f8267d 100644 --- a/library/network/http_client/src/http_client_session.e +++ b/library/network/http_client/src/http_client_session.e @@ -197,11 +197,15 @@ feature -- Authentication auth_type_id: INTEGER -- See {HTTP_CLIENT_CONSTANTS}.Auth_type_* - username, + username: detachable READABLE_STRING_32 + -- Associated optional username value. + password: detachable READABLE_STRING_32 + -- Associated optional password value. credentials: detachable READABLE_STRING_32 - + -- Associated optional credentials value. + -- Computed as `username':`password'. feature -- Status setting diff --git a/library/network/http_client/src/spec/libcurl/libcurl_http_client_session.e b/library/network/http_client/src/spec/libcurl/libcurl_http_client_session.e index b7a8b952..af8e4572 100644 --- a/library/network/http_client/src/spec/libcurl/libcurl_http_client_session.e +++ b/library/network/http_client/src/spec/libcurl/libcurl_http_client_session.e @@ -37,6 +37,7 @@ feature -- Status report 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 @@ -45,11 +46,13 @@ feature -- Custom 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 + -- Same as `custom' but including upload data `a_data'. 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 + -- Same as `custom' but including upload file `fn'. do Result := impl_custom (a_method, a_path, a_ctx, Void, fn) end @@ -57,46 +60,55 @@ feature -- Custom 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 diff --git a/library/network/http_client/src/spec/net/net_http_client_request.e b/library/network/http_client/src/spec/net/net_http_client_request.e index 41c91294..5e8d1ac2 100644 --- a/library/network/http_client/src/spec/net/net_http_client_request.e +++ b/library/network/http_client/src/spec/net/net_http_client_request.e @@ -65,9 +65,6 @@ feature -- Access 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_prev_header: READABLE_STRING_8 l_boundary: READABLE_STRING_8 l_is_http_1_0: BOOLEAN @@ -80,7 +77,6 @@ feature -- Access end create Result.make (url) - -- Get URL data l_is_https := url.starts_with_general ("https://") create l_uri.make_from_string (url) @@ -158,7 +154,6 @@ feature -- Access 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") @@ -166,57 +161,12 @@ feature -- Access headers.force (l_upload_data.count.out, "Content-Length") else - -- create form + -- create form using multipart/form-data encoding l_boundary := new_mime_boundary headers.extend ("multipart/form-data; boundary=" + l_boundary, "Content-Type") if l_form_data /= Void then headers.extend ("*/*", "Accept") - from - l_form_data.start - until - l_form_data.after - loop - l_form_string.append (l_boundary) - 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 - - 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 (l_boundary) - 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_access_readable then - append_file_content_to (l_upload_file, l_upload_file.count, l_form_string) - -- Reset l_upload_file to Void, since the related content is already processed. - l_upload_file := Void - end - l_form_string.append (http_end_of_header_line) - end - l_form_string.append (l_boundary + "--") --| end - - l_upload_data := l_form_string + l_upload_data := form_date_and_uploaded_files_to_mime_string (l_form_data, l_upload_filename, l_boundary) headers.extend (l_upload_data.count.out, "Content-Length") end end @@ -236,7 +186,6 @@ feature -- Access end check l_upload_file /= Void end end - end end @@ -358,16 +307,13 @@ feature -- Access -- follow redirect if l_location /= Void then - if current_redirects < max_redirects then - current_redirects := current_redirects + 1 + if Result.redirections_count < max_redirects then initialize (l_location, ctx) redirection_response := response redirection_response.add_redirection (Result.status_line, Result.raw_header, Result.body) Result := redirection_response end end - - current_redirects := current_redirects - 1 else Result.set_error_message ("Read Timeout") end @@ -388,6 +334,78 @@ feature -- Access feature {NONE} -- Helpers + form_date_and_uploaded_files_to_mime_string (a_form_parameters: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_32]; a_upload_filename: detachable READABLE_STRING_GENERAL; a_mime_boundary: READABLE_STRING_8): STRING + local + l_path: PATH + l_mime_type: READABLE_STRING_8 + l_upload_file: detachable RAW_FILE + l_mime_type_mapping: HTTP_FILE_EXTENSION_MIME_MAPPING + do + create Result.make (100) + across + a_form_parameters as ic + loop + Result.append (a_mime_boundary) + Result.append (http_end_of_header_line) + Result.append ("Content-Disposition: form-data; name=") + Result.append_character ('%"') + Result.append (string_to_mime_encoded_string (ic.key)) + Result.append_character ('%"') + Result.append (http_end_of_header_line) + Result.append (http_end_of_header_line) + Result.append (string_to_mime_encoded_string (ic.item)) + Result.append (http_end_of_header_line) + end + + if a_upload_filename /= Void then + -- get file extension, otherwise set default + create l_mime_type_mapping.make_default + create l_path.make_from_string (a_upload_filename) + if + attached l_path.extension as ext and then + attached l_mime_type_mapping.mime_type (ext) as l_mt + then + l_mime_type := l_mt + else + l_mime_type := "application/octet-stream" + end + + Result.append (a_mime_boundary) + Result.append (http_end_of_header_line) + Result.append ("Content-Disposition: form-data; name=%"") + Result.append (string_to_mime_encoded_string (a_upload_filename)) + Result.append_character ('%"') + Result.append ("; filename=%"") + Result.append (string_to_mime_encoded_string (a_upload_filename)) + Result.append_character ('%"') + Result.append (http_end_of_header_line) + Result.append ("Content-Type: ") + Result.append (l_mime_type) + Result.append (http_end_of_header_line) + Result.append (http_end_of_header_line) + + create l_upload_file.make_with_path (l_path) + if l_upload_file.exists and then l_upload_file.is_access_readable then + append_file_content_to (l_upload_file, l_upload_file.count, Result) + -- Reset l_upload_file to Void, since the related content is already processed. + l_upload_file := Void + end + Result.append (http_end_of_header_line) + end + Result.append (a_mime_boundary) + Result.append ("--") --| end + end + + string_to_mime_encoded_string (s: READABLE_STRING_GENERAL): STRING + -- Encoded unicode string for mime value. + -- For instance uploaded filename, or form data key or values. + local + utf: UTF_CONVERTER + do + -- FIXME: find the proper encoding! + Result := utf.utf_32_string_to_utf_8_string_8 (s) + end + append_file_content_to_socket (a_file: FILE; a_len: INTEGER; a_output: NETWORK_STREAM_SOCKET) -- Append `a_file' content to `a_output'. -- If `a_len' >= 0 then read only `a_len' characters. @@ -488,8 +506,7 @@ feature {NONE} -- Helpers local s: STRING_8 r: INTEGER -- remaining count - n,pos, l_chunk_size, l_count: INTEGER - hexa2int: HEXADECIMAL_STRING_TO_INTEGER_CONVERTER + n,l_chunk_size, l_count: INTEGER do if a_socket.readable then if a_len >= 0 then @@ -519,77 +536,7 @@ feature {NONE} -- Helpers end check full_content_read: not a_response.error_occurred implies l_count = a_len end elseif attached a_response.header ("Transfer-Encoding") as l_enc and then l_enc.is_case_insensitive_equal ("chunked") then - debug ("socket_content") - io.error.put_string ("Chunked encoding%N") - end - from - create hexa2int.make - n := 1 - until - n = 0 or not a_socket.readable - loop - a_socket.read_line_thread_aware -- Read chunk info - s := a_socket.last_string - s.right_adjust - debug ("socket_content") - io.error.put_string (" - chunk info='" + s + "'%N") - end - pos := s.index_of (';', 1) - if pos > 0 then - s.keep_head (pos - 1) - end - if s.is_empty then - n := 0 - else - hexa2int.parse_string_with_type (s, hexa2int.type_integer) - if hexa2int.parse_successful then - n := hexa2int.parsed_integer - else - n := 0 - end - end - debug ("socket_content") - io.error.put_string (" - chunk size=" + n.out + "%N") - end - if n > 0 then - from - r := n - until - r = 0 or else not a_socket.readable or else a_response.error_occurred - loop - if a_socket.ready_for_reading then - a_socket.read_stream_thread_aware (r) - l_count := l_count + a_socket.bytes_read - debug ("socket_content") - io.error.put_string (" - byte read=" + a_socket.bytes_read.out + "%N") - io.error.put_string (" - current count=" + l_count.out + "%N") - end - r := r - a_socket.bytes_read - a_output.append (a_socket.last_string) - else - debug ("socket_content") - io.error.put_string (" -! TIMEOUT%N") - end - a_response.set_error_message ("Could not read chunked data, timeout") - end - end - - if a_socket.ready_for_reading then - a_socket.read_character - check a_socket.last_character = '%R' end - a_socket.read_character - check a_socket.last_character = '%N' end - debug ("socket_content") - io.error.put_string (" - Found CRNL %N") - end - else - debug ("socket_content") - io.error.put_string (" -! TIMEOUT%N") - end - a_response.set_error_message ("Could not read chunked data, timeout") - end - end - end + append_socket_chunked_content_to (a_response, a_socket, a_output) else -- No Content-Length and no chunked transfer encoding! -- maybe HTTP/1.0 ? @@ -615,6 +562,91 @@ feature {NONE} -- Helpers end end + append_socket_chunked_content_to (a_response: HTTP_CLIENT_RESPONSE; a_socket: NETWORK_STREAM_SOCKET; a_output: STRING) + -- Get chunked content from `a_socket' and append it to `a_output'. + require + socket_readable: a_socket.readable + has_chunked_transfer_encoding: attached a_response.header ("Transfer-Encoding") as l_enc and then + l_enc.is_case_insensitive_equal ("chunked") + local + s: STRING_8 + r: INTEGER -- remaining count + n,pos, l_count: INTEGER + hexa2int: HEXADECIMAL_STRING_TO_INTEGER_CONVERTER + do + debug ("socket_content") + io.error.put_string ("Chunked encoding%N") + end + from + create hexa2int.make + n := 1 + until + n = 0 or not a_socket.readable + loop + a_socket.read_line_thread_aware -- Read chunk info + s := a_socket.last_string + s.right_adjust + debug ("socket_content") + io.error.put_string (" - chunk info='" + s + "'%N") + end + pos := s.index_of (';', 1) + if pos > 0 then + s.keep_head (pos - 1) + end + if s.is_empty then + n := 0 + else + hexa2int.parse_string_with_type (s, hexa2int.type_integer) + if hexa2int.parse_successful then + n := hexa2int.parsed_integer + else + n := 0 + end + end + debug ("socket_content") + io.error.put_string (" - chunk size=" + n.out + "%N") + end + if n > 0 then + from + r := n + until + r = 0 or else not a_socket.readable or else a_response.error_occurred + loop + if a_socket.ready_for_reading then + a_socket.read_stream_thread_aware (r) + l_count := l_count + a_socket.bytes_read + debug ("socket_content") + io.error.put_string (" - byte read=" + a_socket.bytes_read.out + "%N") + io.error.put_string (" - current count=" + l_count.out + "%N") + end + r := r - a_socket.bytes_read + a_output.append (a_socket.last_string) + else + debug ("socket_content") + io.error.put_string (" -! TIMEOUT%N") + end + a_response.set_error_message ("Could not read chunked data, timeout") + end + end + + if a_socket.ready_for_reading then + a_socket.read_character + check a_socket.last_character = '%R' end + a_socket.read_character + check a_socket.last_character = '%N' end + debug ("socket_content") + io.error.put_string (" - Found CRNL %N") + end + else + debug ("socket_content") + io.error.put_string (" -! TIMEOUT%N") + end + a_response.set_error_message ("Could not read chunked data, timeout") + end + end + end + end + new_mime_boundary: STRING -- New MIME boundary. do diff --git a/library/network/http_client/src/spec/net/net_http_client_session.e b/library/network/http_client/src/spec/net/net_http_client_session.e index 2c375574..6a6653f5 100644 --- a/library/network/http_client/src/spec/net/net_http_client_session.e +++ b/library/network/http_client/src/spec/net/net_http_client_session.e @@ -36,6 +36,7 @@ feature -- Status report 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 @@ -44,11 +45,13 @@ feature -- Custom 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 + -- Same as `custom' but including upload data `a_data'. 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 + -- Same as `custom' but including upload file `fn'. do Result := impl_custom (a_method, a_path, a_ctx, Void, fn) end @@ -56,46 +59,55 @@ feature -- Custom 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 diff --git a/library/network/http_client/src/spec/null/null_http_client.e b/library/network/http_client/src/spec/null/null_http_client.e deleted file mode 100644 index c2eec1ac..00000000 --- a/library/network/http_client/src/spec/null/null_http_client.e +++ /dev/null @@ -1,33 +0,0 @@ -note - description : "[ - Instantiate one of the descendant of HTTP_CLIENT - then use `new_session' to create a session of http requests - ]" - date : "$Date$" - revision : "$Revision$" - -class - NULL_HTTP_CLIENT - -inherit - HTTP_CLIENT - -feature -- Status - - new_session (a_base_url: READABLE_STRING_8): NULL_HTTP_CLIENT_SESSION - -- Create a new session using `a_base_url'. - 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 diff --git a/library/network/http_client/src/spec/null/null_http_client_session.e b/library/network/http_client/src/spec/null/null_http_client_session.e index 9a766e57..bf5b20ea 100644 --- a/library/network/http_client/src/spec/null/null_http_client_session.e +++ b/library/network/http_client/src/spec/null/null_http_client_session.e @@ -1,11 +1,7 @@ note description : "[ - HTTP_CLIENT_SESSION represents a session - and is used to call get, post, .... request - with predefined settings such as - base_url - specific common headers - timeout and so on ... + NULL version of HTTP_CLIENT_SESSION. + It is used if no implementation is available (libcurl or net) ]" date: "$Date$" revision: "$Revision$" diff --git a/library/network/http_client/tests/test-safe.ecf b/library/network/http_client/tests/test-safe.ecf index 75c48706..8a36c514 100644 --- a/library/network/http_client/tests/test-safe.ecf +++ b/library/network/http_client/tests/test-safe.ecf @@ -11,6 +11,7 @@ + diff --git a/library/network/http_client/tests/test.e b/library/network/http_client/tests/test.e index f5020cb7..869b58ac 100644 --- a/library/network/http_client/tests/test.e +++ b/library/network/http_client/tests/test.e @@ -7,12 +7,11 @@ feature -- Init make local - null: NULL_HTTP_CLIENT + null: NULL_HTTP_CLIENT_SESSION do - create null - if attached null.new_session ("http://example.com/") as l_sess then - check not l_sess.is_available end - end + create null.make ("http://example.com/") + check not null.is_available end + test_get_with_authentication test_http_client end