mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-04-07 09:42:34 +00:00
MINOR: httpclient: support payload within a buffer
httpclient_req_gen() takes a payload argument which can be use to put a payload in the request. This payload can only fit a request buffer. This payload can also be specified by the "body" named parameter within the lua. httpclient. It is also used within the CLI httpclient when specified as a CLI payload with "<<".
This commit is contained in:
parent
b4d0cd02c1
commit
dec25c3e14
@ -9,7 +9,7 @@ struct httpclient *httpclient_new(void *caller, enum http_meth_t meth, struct is
|
|||||||
|
|
||||||
struct appctx *httpclient_start(struct httpclient *hc);
|
struct appctx *httpclient_start(struct httpclient *hc);
|
||||||
int httpclient_res_xfer(struct httpclient *hc, struct buffer *dst);
|
int httpclient_res_xfer(struct httpclient *hc, struct buffer *dst);
|
||||||
int httpclient_req_gen(struct httpclient *hc, const struct ist url, enum http_meth_t meth, const struct http_hdr *hdrs);
|
int httpclient_req_gen(struct httpclient *hc, const struct ist url, enum http_meth_t meth, const struct http_hdr *hdrs, const struct ist payload);
|
||||||
|
|
||||||
|
|
||||||
/* Return the amount of data available in the httpclient response buffer */
|
/* Return the amount of data available in the httpclient response buffer */
|
||||||
|
@ -21,7 +21,7 @@ local function cron()
|
|||||||
core.Debug('CRON port:' .. vtc_port)
|
core.Debug('CRON port:' .. vtc_port)
|
||||||
|
|
||||||
local httpclient = core.httpclient()
|
local httpclient = core.httpclient()
|
||||||
local response = httpclient:get{url="http://127.0.0.1:" .. vtc_port}
|
local response = httpclient:get{url="http://127.0.0.1:" .. vtc_port, body="foobar-is-the-new-toto"}
|
||||||
|
|
||||||
core.Info("Received: " .. response.body)
|
core.Info("Received: " .. response.body)
|
||||||
end
|
end
|
||||||
|
@ -7164,6 +7164,7 @@ __LJMP static int hlua_httpclient_get(lua_State *L)
|
|||||||
struct http_hdr *hdrs_i = NULL;
|
struct http_hdr *hdrs_i = NULL;
|
||||||
struct hlua *hlua;
|
struct hlua *hlua;
|
||||||
const char *url_str = NULL;
|
const char *url_str = NULL;
|
||||||
|
const char *body_str = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
hlua = hlua_gethlua(L);
|
hlua = hlua_gethlua(L);
|
||||||
@ -7187,6 +7188,12 @@ __LJMP static int hlua_httpclient_get(lua_State *L)
|
|||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
ret = lua_getfield(L, -1, "body");
|
||||||
|
if (ret == LUA_TSTRING) {
|
||||||
|
body_str = lua_tostring(L, -1);
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
if (!url_str) {
|
if (!url_str) {
|
||||||
WILL_LJMP(luaL_error(L, "'get' need a 'url' argument"));
|
WILL_LJMP(luaL_error(L, "'get' need a 'url' argument"));
|
||||||
return 0;
|
return 0;
|
||||||
@ -7204,7 +7211,7 @@ __LJMP static int hlua_httpclient_get(lua_State *L)
|
|||||||
hlua_hc->hc->ops.res_end = hlua_httpclient_res_cb;
|
hlua_hc->hc->ops.res_end = hlua_httpclient_res_cb;
|
||||||
|
|
||||||
|
|
||||||
httpclient_req_gen(hlua_hc->hc, hlua_hc->hc->req.url, HTTP_METH_GET, hdrs);
|
httpclient_req_gen(hlua_hc->hc, hlua_hc->hc->req.url, HTTP_METH_GET, hdrs, ist(body_str));
|
||||||
httpclient_start(hlua_hc->hc);
|
httpclient_start(hlua_hc->hc);
|
||||||
|
|
||||||
/* free the temporary headers array */
|
/* free the temporary headers array */
|
||||||
|
@ -116,6 +116,7 @@ static int hc_cli_parse(char **args, char *payload, struct appctx *appctx, void
|
|||||||
enum http_meth_t meth;
|
enum http_meth_t meth;
|
||||||
char *meth_str;
|
char *meth_str;
|
||||||
struct ist uri;
|
struct ist uri;
|
||||||
|
struct ist body = IST_NULL;
|
||||||
|
|
||||||
if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
|
if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
|
||||||
return 1;
|
return 1;
|
||||||
@ -128,6 +129,9 @@ static int hc_cli_parse(char **args, char *payload, struct appctx *appctx, void
|
|||||||
meth_str = args[1];
|
meth_str = args[1];
|
||||||
uri = ist(args[2]);
|
uri = ist(args[2]);
|
||||||
|
|
||||||
|
if (payload)
|
||||||
|
body = ist(payload);
|
||||||
|
|
||||||
meth = find_http_meth(meth_str, strlen(meth_str));
|
meth = find_http_meth(meth_str, strlen(meth_str));
|
||||||
|
|
||||||
hc = httpclient_new(appctx, meth, uri);
|
hc = httpclient_new(appctx, meth, uri);
|
||||||
@ -144,7 +148,7 @@ static int hc_cli_parse(char **args, char *payload, struct appctx *appctx, void
|
|||||||
appctx->ctx.cli.p0 = hc; /* store the httpclient ptr in the applet */
|
appctx->ctx.cli.p0 = hc; /* store the httpclient ptr in the applet */
|
||||||
appctx->ctx.cli.i0 = 0;
|
appctx->ctx.cli.i0 = 0;
|
||||||
|
|
||||||
if (httpclient_req_gen(hc, hc->req.url, hc->req.meth, default_httpclient_hdrs) != ERR_NONE)
|
if (httpclient_req_gen(hc, hc->req.url, hc->req.meth, default_httpclient_hdrs, body) != ERR_NONE)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
|
||||||
@ -253,13 +257,13 @@ INITCALL1(STG_REGISTER, cli_register_kw, &cli_kws);
|
|||||||
* If the buffer was filled correctly the function returns 0, if not it returns
|
* If the buffer was filled correctly the function returns 0, if not it returns
|
||||||
* an error_code but there is no guarantee that the buffer wasn't modified.
|
* an error_code but there is no guarantee that the buffer wasn't modified.
|
||||||
*/
|
*/
|
||||||
int httpclient_req_gen(struct httpclient *hc, const struct ist url, enum http_meth_t meth, const struct http_hdr *hdrs)
|
int httpclient_req_gen(struct httpclient *hc, const struct ist url, enum http_meth_t meth, const struct http_hdr *hdrs, const struct ist payload)
|
||||||
{
|
{
|
||||||
struct htx_sl *sl;
|
struct htx_sl *sl;
|
||||||
struct htx *htx;
|
struct htx *htx;
|
||||||
int err_code = 0;
|
int err_code = 0;
|
||||||
struct ist meth_ist, vsn;
|
struct ist meth_ist, vsn;
|
||||||
unsigned int flags = HTX_SL_F_VER_11 | HTX_SL_F_BODYLESS | HTX_SL_F_XFER_LEN | HTX_SL_F_NORMALIZED_URI | HTX_SL_F_HAS_SCHM;
|
unsigned int flags = HTX_SL_F_VER_11 | HTX_SL_F_NORMALIZED_URI | HTX_SL_F_HAS_SCHM;
|
||||||
|
|
||||||
if (meth >= HTTP_METH_OTHER)
|
if (meth >= HTTP_METH_OTHER)
|
||||||
goto error;
|
goto error;
|
||||||
@ -292,6 +296,13 @@ int httpclient_req_gen(struct httpclient *hc, const struct ist url, enum http_me
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isttest(payload)) {
|
||||||
|
/* add the payload if it can feat in the buffer, no need to set
|
||||||
|
* the Content-Length, the data will be sent chunked */
|
||||||
|
if (!htx_add_data_atonce(htx, payload))
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
htx->flags |= HTX_FL_EOM;
|
htx->flags |= HTX_FL_EOM;
|
||||||
|
|
||||||
htx_to_buf(htx, &hc->req.buf);
|
htx_to_buf(htx, &hc->req.buf);
|
||||||
|
Loading…
Reference in New Issue
Block a user