mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-16 05:46:25 +00:00
Add support for the -i
(include headers) and -d
(POST data) options in curl.com
(#708)
This commit also paves the way for initial IPv6 support in `curl.com` by specifying `AF_UNSPEC` for the address family in the hints passed to `getaddrinfo()`.
This commit is contained in:
parent
2e5181666f
commit
d2f811eff3
1 changed files with 29 additions and 9 deletions
|
@ -115,7 +115,7 @@ static int TlsRecv(void *c, unsigned char *p, size_t n, uint32_t o) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static wontreturn void PrintUsage(FILE *f, int rc) {
|
static wontreturn void PrintUsage(FILE *f, int rc) {
|
||||||
fprintf(f, "usage: %s [-ksvV] URL\n", program_invocation_name);
|
fprintf(f, "usage: %s [-iksvV] URL\n", program_invocation_name);
|
||||||
exit(rc);
|
exit(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,11 +130,13 @@ int _curl(int argc, char *argv[]) {
|
||||||
size_t n;
|
size_t n;
|
||||||
char **p;
|
char **p;
|
||||||
} headers = {0};
|
} headers = {0};
|
||||||
int method = kHttpGet;
|
int method = 0;
|
||||||
bool authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
|
bool authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
|
||||||
|
bool includeheaders = false;
|
||||||
|
const char *postdata = NULL;
|
||||||
const char *agent = "hurl/1.o (https://github.com/jart/cosmopolitan)";
|
const char *agent = "hurl/1.o (https://github.com/jart/cosmopolitan)";
|
||||||
__log_level = kLogWarn;
|
__log_level = kLogWarn;
|
||||||
while ((opt = getopt(argc, argv, "qksvVIX:H:A:")) != -1) {
|
while ((opt = getopt(argc, argv, "qiksvVIX:H:A:d:")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 's':
|
case 's':
|
||||||
case 'q':
|
case 'q':
|
||||||
|
@ -142,6 +144,9 @@ int _curl(int argc, char *argv[]) {
|
||||||
case 'v':
|
case 'v':
|
||||||
++__log_level;
|
++__log_level;
|
||||||
break;
|
break;
|
||||||
|
case 'i':
|
||||||
|
includeheaders = true;
|
||||||
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
method = kHttpHead;
|
method = kHttpHead;
|
||||||
break;
|
break;
|
||||||
|
@ -152,6 +157,9 @@ int _curl(int argc, char *argv[]) {
|
||||||
headers.p = realloc(headers.p, ++headers.n * sizeof(*headers.p));
|
headers.p = realloc(headers.p, ++headers.n * sizeof(*headers.p));
|
||||||
headers.p[headers.n - 1] = optarg;
|
headers.p[headers.n - 1] = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'd':
|
||||||
|
postdata = optarg;
|
||||||
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
CHECK((method = GetHttpMethod(optarg, strlen(optarg))));
|
CHECK((method = GetHttpMethod(optarg, strlen(optarg))));
|
||||||
break;
|
break;
|
||||||
|
@ -222,17 +230,29 @@ int _curl(int argc, char *argv[]) {
|
||||||
/*
|
/*
|
||||||
* Create HTTP message.
|
* Create HTTP message.
|
||||||
*/
|
*/
|
||||||
|
if (!method) method = postdata ? kHttpPost : kHttpGet;
|
||||||
|
|
||||||
char *request = 0;
|
char *request = 0;
|
||||||
appendf(&request,
|
appendf(&request,
|
||||||
"%s %s HTTP/1.1\r\n"
|
"%s %s HTTP/1.1\r\n"
|
||||||
"Host: %s:%s\r\n"
|
|
||||||
"Connection: close\r\n"
|
"Connection: close\r\n"
|
||||||
"User-Agent: %s\r\n",
|
"User-Agent: %s\r\n",
|
||||||
kHttpMethod[method], _gc(EncodeUrl(&url, 0)), host, port, agent);
|
kHttpMethod[method], _gc(EncodeUrl(&url, 0)), agent);
|
||||||
|
|
||||||
|
bool senthost = false, sentcontenttype = false, sentcontentlength = false;
|
||||||
for (int i = 0; i < headers.n; ++i) {
|
for (int i = 0; i < headers.n; ++i) {
|
||||||
appendf(&request, "%s\r\n", headers.p[i]);
|
appendf(&request, "%s\r\n", headers.p[i]);
|
||||||
|
if (!strncasecmp("Host:", headers.p[i], 5)) senthost = true;
|
||||||
|
else if (!strncasecmp("Content-Type:", headers.p[i], 13)) sentcontenttype = true;
|
||||||
|
else if (!strncasecmp("Content-Length:", headers.p[i], 15)) sentcontentlength = true;
|
||||||
|
}
|
||||||
|
if (!senthost) appendf(&request, "Host: %s:%s\r\n", host, port);
|
||||||
|
if (postdata) {
|
||||||
|
if (!sentcontenttype) appends(&request, "Content-Type: application/x-www-form-urlencoded\r\n");
|
||||||
|
if (!sentcontentlength) appendf(&request, "Content-Length: %d\r\n", strlen(postdata));
|
||||||
}
|
}
|
||||||
appendf(&request, "\r\n");
|
appendf(&request, "\r\n");
|
||||||
|
if (postdata) appends(&request, postdata);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup crypto.
|
* Setup crypto.
|
||||||
|
@ -260,7 +280,7 @@ int _curl(int argc, char *argv[]) {
|
||||||
* Perform DNS lookup.
|
* Perform DNS lookup.
|
||||||
*/
|
*/
|
||||||
struct addrinfo *addr;
|
struct addrinfo *addr;
|
||||||
struct addrinfo hints = {.ai_family = AF_INET,
|
struct addrinfo hints = {.ai_family = AF_UNSPEC,
|
||||||
.ai_socktype = SOCK_STREAM,
|
.ai_socktype = SOCK_STREAM,
|
||||||
.ai_protocol = IPPROTO_TCP,
|
.ai_protocol = IPPROTO_TCP,
|
||||||
.ai_flags = AI_NUMERICSERV};
|
.ai_flags = AI_NUMERICSERV};
|
||||||
|
@ -342,10 +362,10 @@ int _curl(int argc, char *argv[]) {
|
||||||
i -= hdrlen;
|
i -= hdrlen;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (method == kHttpHead) {
|
if (method == kHttpHead || includeheaders) {
|
||||||
Write(p, hdrlen);
|
Write(p, hdrlen);
|
||||||
goto Finished;
|
}
|
||||||
} else if (msg.status == 204 || msg.status == 304) {
|
if (method == kHttpHead || msg.status == 204 || msg.status == 304) {
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
if (HasHeader(kHttpTransferEncoding) &&
|
if (HasHeader(kHttpTransferEncoding) &&
|
||||||
|
|
Loading…
Add table
Reference in a new issue