mirror of
https://github.com/curl/curl.git
synced 2025-09-16 17:12:43 +03:00
curl: add --url-query
This option adds a piece of data, usually a name + value pair, to the end of the URL query part. The syntax is identical to that used for --data-urlencode with one extension: If the argument starts with a '+' (plus), the rest of the string is provided as-is unencoded. This allows users to "build" query parts with options and URL encoding even when not doing GET requests, which the already provided option -G (--get) is limited to. This idea was born in a Twitter thread. Closes #9691
This commit is contained in:
parent
43232b5992
commit
b6e1afd069
|
@ -265,6 +265,7 @@ DPAGES = \
|
||||||
unix-socket.d \
|
unix-socket.d \
|
||||||
upload-file.d \
|
upload-file.d \
|
||||||
url.d \
|
url.d \
|
||||||
|
url-query.d \
|
||||||
use-ascii.d \
|
use-ascii.d \
|
||||||
user-agent.d \
|
user-agent.d \
|
||||||
user.d \
|
user.d \
|
||||||
|
|
25
docs/cmdline-opts/url-query.d
Normal file
25
docs/cmdline-opts/url-query.d
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
c: Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
SPDX-License-Identifier: curl
|
||||||
|
Long: url-query
|
||||||
|
Arg: <data>
|
||||||
|
Help: Add a URL query part
|
||||||
|
Protocols: all
|
||||||
|
See-also: data-urlencode get
|
||||||
|
Added: 7.87.0
|
||||||
|
Category: http post upload
|
||||||
|
Example: --url-query name=val $URL
|
||||||
|
Example: --url-query =encodethis http://example.net/foo
|
||||||
|
Example: --url-query name@file $URL
|
||||||
|
Example: --url-query @fileonly $URL
|
||||||
|
Example: --url-query "+name=%20foo" $URL
|
||||||
|
Multi: append
|
||||||
|
---
|
||||||
|
This option adds a piece of data, usually a name + value pair, to the end of
|
||||||
|
the URL query part. The syntax is identical to that used for --data-urlencode
|
||||||
|
with one extension:
|
||||||
|
|
||||||
|
If the argument starts with a '+' (plus), the rest of the string is provided
|
||||||
|
as-is unencoded.
|
||||||
|
|
||||||
|
The query part of a URL is the one following the question mark on the right
|
||||||
|
end.
|
|
@ -251,6 +251,7 @@
|
||||||
--unix-socket 7.40.0
|
--unix-socket 7.40.0
|
||||||
--upload-file (-T) 4.0
|
--upload-file (-T) 4.0
|
||||||
--url 7.5
|
--url 7.5
|
||||||
|
--url-query 7.87.0
|
||||||
--use-ascii (-B) 5.0
|
--use-ascii (-B) 5.0
|
||||||
--user (-u) 4.0
|
--user (-u) 4.0
|
||||||
--user-agent (-A) 4.5.1
|
--user-agent (-A) 4.5.1
|
||||||
|
|
|
@ -58,6 +58,7 @@ static void free_config_fields(struct OperationConfig *config)
|
||||||
curl_slist_free_all(config->cookiefiles);
|
curl_slist_free_all(config->cookiefiles);
|
||||||
|
|
||||||
Curl_safefree(config->postfields);
|
Curl_safefree(config->postfields);
|
||||||
|
Curl_safefree(config->query);
|
||||||
Curl_safefree(config->referer);
|
Curl_safefree(config->referer);
|
||||||
|
|
||||||
Curl_safefree(config->headerfile);
|
Curl_safefree(config->headerfile);
|
||||||
|
|
|
@ -70,6 +70,7 @@ struct OperationConfig {
|
||||||
char *postfields;
|
char *postfields;
|
||||||
curl_off_t postfieldsize;
|
curl_off_t postfieldsize;
|
||||||
char *referer;
|
char *referer;
|
||||||
|
char *query;
|
||||||
long timeout_ms;
|
long timeout_ms;
|
||||||
long connecttimeout_ms;
|
long connecttimeout_ms;
|
||||||
long maxredirs;
|
long maxredirs;
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "tool_paramhlp.h"
|
#include "tool_paramhlp.h"
|
||||||
#include "tool_parsecfg.h"
|
#include "tool_parsecfg.h"
|
||||||
#include "tool_main.h"
|
#include "tool_main.h"
|
||||||
|
#include "dynbuf.h"
|
||||||
|
|
||||||
#include "memdebug.h" /* keep this as LAST include */
|
#include "memdebug.h" /* keep this as LAST include */
|
||||||
|
|
||||||
|
@ -233,6 +234,7 @@ static const struct LongShort aliases[]= {
|
||||||
{"db", "data-binary", ARG_STRING},
|
{"db", "data-binary", ARG_STRING},
|
||||||
{"de", "data-urlencode", ARG_STRING},
|
{"de", "data-urlencode", ARG_STRING},
|
||||||
{"df", "json", ARG_STRING},
|
{"df", "json", ARG_STRING},
|
||||||
|
{"dg", "url-query", ARG_STRING},
|
||||||
{"D", "dump-header", ARG_FILENAME},
|
{"D", "dump-header", ARG_FILENAME},
|
||||||
{"e", "referer", ARG_STRING},
|
{"e", "referer", ARG_STRING},
|
||||||
{"E", "cert", ARG_FILENAME},
|
{"E", "cert", ARG_FILENAME},
|
||||||
|
@ -1567,7 +1569,39 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
bool raw_mode = (subletter == 'r');
|
bool raw_mode = (subletter == 'r');
|
||||||
|
|
||||||
if(subletter == 'e') { /* --data-urlencode */
|
if(subletter == 'g') { /* --url-query */
|
||||||
|
#define MAX_QUERY_LEN 100000 /* larger is not likely to ever work */
|
||||||
|
char *query;
|
||||||
|
struct curlx_dynbuf dyn;
|
||||||
|
curlx_dyn_init(&dyn, MAX_QUERY_LEN);
|
||||||
|
|
||||||
|
if(*nextarg == '+') {
|
||||||
|
/* use without encoding */
|
||||||
|
query = strdup(&nextarg[1]);
|
||||||
|
if(!query)
|
||||||
|
return PARAM_NO_MEM;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
err = data_urlencode(global, nextarg, &query, &size);
|
||||||
|
if(err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(config->query) {
|
||||||
|
CURLcode result =
|
||||||
|
curlx_dyn_addf(&dyn, "%s&%s", config->query, query);
|
||||||
|
free(query);
|
||||||
|
if(result)
|
||||||
|
return PARAM_NO_MEM;
|
||||||
|
free(config->query);
|
||||||
|
config->query = curlx_dyn_ptr(&dyn);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
config->query = query;
|
||||||
|
|
||||||
|
break; /* this is not a POST argument at all */
|
||||||
|
}
|
||||||
|
else if(subletter == 'e') { /* --data-urlencode */
|
||||||
err = data_urlencode(global, nextarg, &postdata, &size);
|
err = data_urlencode(global, nextarg, &postdata, &size);
|
||||||
if(err)
|
if(err)
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -756,6 +756,9 @@ const struct helptxt helptext[] = {
|
||||||
{" --url <url>",
|
{" --url <url>",
|
||||||
"URL to work with",
|
"URL to work with",
|
||||||
CURLHELP_CURL},
|
CURLHELP_CURL},
|
||||||
|
{" --url-query <data>",
|
||||||
|
"Add a URL query part",
|
||||||
|
CURLHELP_HTTP | CURLHELP_POST | CURLHELP_UPLOAD},
|
||||||
{"-B, --use-ascii",
|
{"-B, --use-ascii",
|
||||||
"Use ASCII/text transfer",
|
"Use ASCII/text transfer",
|
||||||
CURLHELP_MISC},
|
CURLHELP_MISC},
|
||||||
|
|
|
@ -1189,14 +1189,14 @@ static CURLcode single_transfer(struct GlobalConfig *global,
|
||||||
global->isatty = orig_isatty;
|
global->isatty = orig_isatty;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(httpgetfields) {
|
if(httpgetfields || config->query) {
|
||||||
|
char *q = httpgetfields ? httpgetfields : config->query;
|
||||||
CURLU *uh = curl_url();
|
CURLU *uh = curl_url();
|
||||||
if(uh) {
|
if(uh) {
|
||||||
char *updated;
|
char *updated;
|
||||||
if(curl_url_set(uh, CURLUPART_URL, per->this_url,
|
if(curl_url_set(uh, CURLUPART_URL, per->this_url,
|
||||||
CURLU_GUESS_SCHEME) ||
|
CURLU_GUESS_SCHEME) ||
|
||||||
curl_url_set(uh, CURLUPART_QUERY, httpgetfields,
|
curl_url_set(uh, CURLUPART_QUERY, q, CURLU_APPENDQUERY) ||
|
||||||
CURLU_APPENDQUERY) ||
|
|
||||||
curl_url_get(uh, CURLUPART_URL, &updated, CURLU_GUESS_SCHEME)) {
|
curl_url_get(uh, CURLUPART_URL, &updated, CURLU_GUESS_SCHEME)) {
|
||||||
curl_url_cleanup(uh);
|
curl_url_cleanup(uh);
|
||||||
result = CURLE_OUT_OF_MEMORY;
|
result = CURLE_OUT_OF_MEMORY;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user