Merge changes from Javier

- update on RESTbuck examples
- new example
- fixed bad typo in WSF_REQUEST

Reverted some changes such as
- http_client_response: keep the headers as a list to handle multiple message-value with same message-name

Fixed simple and simple_file example
Improved HTTP_HEADER

Changed libcurl implementation for http client
- now the header from the context really overwrite any of the session headers
- better design which is more strict, and remove any doubt about context's header usage
This commit is contained in:
Jocelyn Fiat
2011-12-12 16:03:38 +01:00
38 changed files with 779 additions and 186 deletions

View File

@@ -12,16 +12,25 @@ inherit
feature {NONE} -- Initialization
make (a_url: READABLE_STRING_8; a_session: like session)
make (a_url: READABLE_STRING_8; a_session: like session; ctx: like context)
-- Initialize `Current'.
do
session := a_session
url := a_url
headers := session.headers.twin
if ctx /= Void then
context := ctx
import (ctx)
end
ensure
context_set: context = ctx
ctx_header_set: ctx /= Void implies across ctx.headers as ctx_h all attached headers.item (ctx_h.key) as v and then v.same_string (ctx_h.item) end
end
session: HTTP_CLIENT_SESSION
context: detachable HTTP_CLIENT_REQUEST_CONTEXT
feature -- Access
request_method: READABLE_STRING_8
@@ -32,14 +41,23 @@ feature -- Access
headers: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]
feature -- Execution
feature {HTTP_CLIENT_SESSION} -- Execution
import (ctx: HTTP_CLIENT_REQUEST_CONTEXT)
local
l_headers: like headers
do
headers.fill (ctx.headers)
l_headers := headers
across
ctx.headers as ctx_headers
loop
--| fill header from `ctx'
--| and use `force' to overwrite the "session" value if any
l_headers.force (ctx_headers.item, ctx_headers.key)
end
end
execute (ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_RESPONSE
execute: HTTP_CLIENT_RESPONSE
deferred
end

View File

@@ -41,8 +41,43 @@ feature -- Access
raw_header: READABLE_STRING_8
-- Raw http header of the response.
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
--| See: http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html
--| Multiple message-header fields with the same field-name MAY be present in a message
--| if and only if the entire field-value for that header field is defined as a comma-separated list [i.e., #(values)].
--| It MUST be possible to combine the multiple header fields into one "field-name: field-value" pair,
--| without changing the semantics of the message, by appending each subsequent field-value to the first, each separated by a comma.
--| The order in which header fields with the same field-name are received is therefore significant
--| to the interpretation of the combined field value, and thus a proxy MUST NOT change the order of
--| these field values when a message is forwarded.
local
s: detachable STRING_8
k,v: READABLE_STRING_8
do
across
headers as hds
loop
k := hds.item.key
if k.same_string (a_name) then
v := hds.item.value
if s = Void then
create s.make_from_string (v)
else
s.append_character (',')
s.append (v)
end
end
end
Result := s
end
headers: LIST [TUPLE [key: READABLE_STRING_8; value: READABLE_STRING_8]]
-- Computed table of http headers of the response.
--| We use a LIST since one might have multiple message-header fields with the same field-name
--| Then the user can handle those case using default or custom concatenation
--| (note: `header' is concatenating using comma)
local
tb: like internal_headers
pos, l_start, l_end, n, c: INTEGER
@@ -126,6 +161,6 @@ feature -- Change
feature {NONE} -- Implementation
internal_headers: detachable ARRAYED_LIST [TUPLE [key: READABLE_STRING_8; value: READABLE_STRING_8]]
-- Internal cached value for the headers
-- Internal cached value for the headers
end

View File

@@ -20,9 +20,9 @@ create
feature {NONE} -- Initialization
make (a_url: READABLE_STRING_8; a_request_method: like request_method; a_session: like session)
make (a_url: READABLE_STRING_8; a_request_method: like request_method; a_session: like session; ctx: like context)
do
make_request (a_url, a_session)
make_request (a_url, a_session, ctx)
request_method := a_request_method
end
@@ -34,7 +34,7 @@ feature -- Access
feature -- Execution
execute (ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_RESPONSE
execute: HTTP_CLIENT_RESPONSE
local
l_result: INTEGER
l_curl_string: CURL_STRING
@@ -45,7 +45,9 @@ feature -- Execution
curl: CURL_EXTERNALS
curl_easy: CURL_EASY_EXTERNALS
curl_handle: POINTER
ctx: like context
do
ctx := context
curl := session.curl
curl_easy := session.curl_easy
@@ -167,7 +169,15 @@ feature -- Execution
p := curl.slist_append (p, curs.key + ": " + curs.item)
end
end
if ctx /= Void then
if attached ctx.headers as l_headers_2 then
across
l_headers_2 as curs_2
loop
p := curl.slist_append (p, curs_2.key + ": " + curs_2.item)
end
end
end
p := curl.slist_append (p, "Expect:")
curl_easy.setopt_slist (curl_handle, {CURL_OPT_CONSTANTS}.curlopt_httpheader, p)

View File

@@ -27,16 +27,16 @@ feature -- Basic operation
local
req: HTTP_CLIENT_REQUEST
do
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, "GET", Current)
Result := execute_request (req, ctx)
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, "GET", Current, ctx)
Result := req.execute
end
head (a_path: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_RESPONSE
local
req: HTTP_CLIENT_REQUEST
do
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, "HEAD", Current)
Result := execute_request (req, ctx)
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, "HEAD", Current, ctx)
Result := req.execute
end
post (a_path: READABLE_STRING_8; a_ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT; data: detachable READABLE_STRING_8): HTTP_CLIENT_RESPONSE
@@ -54,7 +54,6 @@ feature -- Basic operation
req: HTTP_CLIENT_REQUEST
ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT
do
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, "POST", Current)
ctx := a_ctx
if data /= Void then
if ctx = Void then
@@ -68,7 +67,8 @@ feature -- Basic operation
end
ctx.set_upload_filename (fn)
end
Result := execute_request (req, ctx)
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, "POST", Current, ctx)
Result := req.execute
end
put (a_path: READABLE_STRING_8; a_ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT; data: detachable READABLE_STRING_8): HTTP_CLIENT_RESPONSE
@@ -76,7 +76,6 @@ feature -- Basic operation
req: HTTP_CLIENT_REQUEST
ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT
do
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, "PUT", Current)
ctx := a_ctx
if data /= Void then
if ctx = Void then
@@ -84,7 +83,8 @@ feature -- Basic operation
end
ctx.set_upload_data (data)
end
Result := execute_request (req, ctx)
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, "PUT", Current, ctx)
Result := req.execute
end
put_file (a_path: READABLE_STRING_8; a_ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT; fn: detachable READABLE_STRING_8): HTTP_CLIENT_RESPONSE
@@ -92,7 +92,6 @@ feature -- Basic operation
req: HTTP_CLIENT_REQUEST
ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT
do
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, "PUT", Current)
ctx := a_ctx
if fn /= Void then
if ctx = Void then
@@ -100,25 +99,16 @@ feature -- Basic operation
end
ctx.set_upload_filename (fn)
end
Result := execute_request (req, ctx)
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, "PUT", Current, ctx)
Result := req.execute
end
delete (a_path: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_RESPONSE
local
req: HTTP_CLIENT_REQUEST
do
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, "DELETE", Current)
Result := execute_request (req, ctx)
end
feature {NONE} -- Implementation
execute_request (req: HTTP_CLIENT_REQUEST; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_RESPONSE
do
if ctx /= Void then
req.import (ctx)
end
Result := req.execute (ctx)
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, "DELETE", Current, ctx)
Result := req.execute
end
feature {LIBCURL_HTTP_CLIENT_REQUEST} -- Curl implementation