From 74e96d7816bd5a5338cf9de3c42db03ec71f0f8f Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Fri, 13 Sep 2013 14:50:07 +0200 Subject: [PATCH] Added PATCH support in http_client, and provided custom_with_upload_data and custom_with_upload_file. --- .../http_client/src/http_client_session.e | 18 ++- .../libcurl/libcurl_http_client_request.e | 2 + .../libcurl/libcurl_http_client_session.e | 106 ++++++++++-------- 3 files changed, 77 insertions(+), 49 deletions(-) diff --git a/library/network/http_client/src/http_client_session.e b/library/network/http_client/src/http_client_session.e index a0aeec09..831d399f 100644 --- a/library/network/http_client/src/http_client_session.e +++ b/library/network/http_client/src/http_client_session.e @@ -76,11 +76,15 @@ feature -- Basic operation end end +feature -- Custom + custom (a_method: READABLE_STRING_8; a_path: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_RESPONSE -- Response for `a_method' request based on Current, `a_path' and `ctx'. deferred end +feature -- Helper + get (a_path: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_RESPONSE -- Response for GET request based on Current, `a_path' and `ctx'. deferred @@ -103,6 +107,18 @@ feature -- Basic operation deferred end + patch (a_path: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT; data: detachable READABLE_STRING_8): HTTP_CLIENT_RESPONSE + -- Response for PATCH request based on Current, `a_path' and `ctx' + -- with input `data' + deferred + end + + patch_file (a_path: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT; fn: detachable READABLE_STRING_8): HTTP_CLIENT_RESPONSE + -- Response for PATCH request based on Current, `a_path' and `ctx' + -- with uploaded data file `fn' + deferred + end + put (a_path: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT; data: detachable READABLE_STRING_8): HTTP_CLIENT_RESPONSE -- Response for PUT request based on Current, `a_path' and `ctx' -- with input `data' @@ -281,7 +297,7 @@ feature -- Element change end note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software diff --git a/library/network/http_client/src/spec/libcurl/libcurl_http_client_request.e b/library/network/http_client/src/spec/libcurl/libcurl_http_client_request.e index 083ca687..0dcb127a 100644 --- a/library/network/http_client/src/spec/libcurl/libcurl_http_client_request.e +++ b/library/network/http_client/src/spec/libcurl/libcurl_http_client_request.e @@ -162,6 +162,7 @@ feature -- Execution check post_or_put_request_method: request_method.is_case_insensitive_equal ("POST") or request_method.is_case_insensitive_equal ("PUT") + or request_method.is_case_insensitive_equal ("PATCH") end curl_easy.setopt_string (curl_handle, {CURL_OPT_CONSTANTS}.curlopt_postfields, l_upload_data) @@ -170,6 +171,7 @@ feature -- Execution check post_or_put_request_method: request_method.is_case_insensitive_equal ("POST") or request_method.is_case_insensitive_equal ("PUT") + or request_method.is_case_insensitive_equal ("PATCH") end create l_upload_file.make_with_name (l_upload_filename) 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 d68eb98b..bffe43c5 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 @@ -31,7 +31,7 @@ feature -- Status report Result := curl.is_dynamic_library_exists end -feature -- Basic operation +feature -- Custom custom (a_method: READABLE_STRING_8; a_path: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_RESPONSE local @@ -41,6 +41,18 @@ feature -- Basic operation Result := req.execute 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) @@ -53,63 +65,32 @@ feature -- Basic operation post (a_path: READABLE_STRING_8; a_ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT; data: detachable READABLE_STRING_8): HTTP_CLIENT_RESPONSE do - Result := impl_post (a_path, a_ctx, data, Void) + 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_post (a_path, a_ctx, Void, fn) + 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 - local - ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT - f: detachable RAW_FILE - l_data: detachable READABLE_STRING_8 do - --| Quick and dirty hack using real file, for PUT uploaded data - --| FIXME [2012-05-23]: better use libcurl for that purpose - ctx := a_ctx - if data /= Void then - if ctx = Void then - create ctx.make - end - ctx.set_upload_data (data) - end - if ctx /= Void then - l_data := ctx.upload_data - end - if l_data /= Void then - 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 - Result := custom ("PUT", a_path, ctx) - 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 + 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 - local - ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT do - ctx := a_ctx - if fn /= Void then - if ctx = Void then - create ctx.make - end - ctx.set_upload_filename (fn) - end - Result := custom ("PUT", a_path, ctx) + 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 @@ -119,10 +100,12 @@ feature -- Basic operation feature {NONE} -- Implementation - impl_post (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 + 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 @@ -137,8 +120,35 @@ feature {NONE} -- Implementation end ctx.set_upload_filename (fn) end - create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, "POST", Current, ctx) + 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 {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, a_method, Current, ctx) Result := req.execute + + 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 feature {LIBCURL_HTTP_CLIENT_REQUEST} -- Curl implementation