#include "tlse.h"
+#define DEBUG(lvl, ...) if (debuglevel >= lvl ) { fprintf(stderr, __VA_ARGS__); }
+
struct tls_uri {
char *scheme;
char *userinfo;
}
}
+static int debuglevel = 0;
+
#if 0
static void hexbin(uint8_t *dst, unsigned char *src, size_t len) {
size_t i;
*len = 0;
hlen = strlen(header);
+
+ /* TODO can't do this, buffer may not be zero terminated */
eoh = strstr(io->response.buffer, "\r\n\r\n");
if (!eoh) {
return 0;
}
+
soh = io->response.buffer;
do {
+ /* skip the first line for some reason */
soh = strstr(soh, "\r\n");
if (soh == eoh) {
break;
}
soh += 2;
- if (!memcmp(soh, header, hlen)) {
+ /* done if not enough room */
+ if (hlen > (size_t)(eoh - soh)) {
+ break;
+ }
+ if (!strncasecmp(soh, header, hlen)) {
break;
}
} while (soh < eoh);
case 302:
case 303:
case 307:
+ DEBUG(1, "looking for Location header\n");
hval = find_header(io, "Location:", &hlen);
if (hval) {
io->redirect = strndup(hval, hlen);
ltc_mp = tfm_desc;
- while ((option = getopt(ac, av, "o:OrIfz:np#RL:SkKU:")) != -1) {
+ while ((option = getopt(ac, av, "do:OrIfz:np#RL:SkKU:")) != -1) {
switch (option) {
+ case 'd': debuglevel++; break;
case 'o': outfile = optarg; break;
case 'O': calcoutfile = 1; break;
case 'S': printstatus = 1; head = 1; break;
if (!strcmp(uri.scheme, "https")) {
use_tls = 1;
+ DEBUG(1, "creating tls context\n");
clientssl = tls_create_context(TLS_CLIENT, TLS_V12);
/* optionally, we can set a certificate validation
fprintf(stderr, "Error loading root certs\n");
return 1;
}
+ DEBUG(1, "verifying ssl cert via roots\n");
tls_set_verify(clientssl, verify_roots);
} else if (verifypolicy == 1) {
+ DEBUG(1, "verifying ssl cert via first use\n");
tls_set_verify(clientssl, verify_first);
+ DEBUG(1, "verified ssl cert via first use\n");
} else {
+ DEBUG(1, "verifying ssl cert via trust\n");
tls_set_verify(clientssl, verify_trust);
}
return -1;
}
tls_sni_set(clientssl, uri.host);
+ DEBUG(1, "set sni to %s\n", uri.host);
clientssl->sync = 1;
io.tls = clientssl;
sockfd = open_tcp_connection(host, port);
+ DEBUG(1, "opened tcp socket fd %d\n", sockfd);
if (sockfd < 0) {
perror("can't open connection");
exit(EXIT_FAILURE);
exit(EXIT_FAILURE);
}
+ DEBUG(1, "wrote http request\n");
if (ret == -1) {
fprintf(stderr, "unable to write http request: %s\n", strerror(errno));
exit(EXIT_FAILURE);
eoh = strstr(io.response.buffer, "\r\n\r\n");
}
if (!eoh) {
+ DEBUG(1, "filling buffer\n");
ret = fill_buffer(&io);
if (ret <= 0) {
break;
}
}
} while (!eoh);
+ DEBUG(1, "got response\n");
if (!eoh) {
/* never got (complete) header */
}
header_len = (size_t)(eoh - io.response.buffer) + 4;
+ fprintf(stderr, "%*s\n", (int)header_len, io.response.buffer);
parse_header(&io);
+ DEBUG(1, "parsed response header, code %d\n", io.status_code);
switch (io.status_code) {
case 304:
case 302:
case 303:
case 307:
+ DEBUG(1, "redirecting to %s\n", io.redirect);
free(url);
url = strdup(io.redirect);
+ DEBUG(1, "redirecting to %s\n", url);
close(io.socket);
continue;
break;
if (head) {
io.response.len -= 2;
+ write(out, io.response.buffer, io.response.len);
+ break;
+ }
+
+ if (io.status_code == 304) {
+ break;
}
if (outfile) {
}
}
- if (head) {
- write(out, io.response.buffer, io.response.len);
- break;
- }
-
if (raw) {
write(out, io.response.buffer, header_len);
}
}
do {
+ size_t before = io.received;
if (io.response.len) {
if (io.content_length && io.response.len + io.received > io.content_length) {
io.response.len = io.content_length - io.received;
if (progressbar) {
if (io.content_length) {
- pdots(50, '.', total, total+ret,
+ pdots(50, '.', before, io.received,
io.content_length);
} else {
putc('\r', stderr);
close(sockfd);
if (progressbar && io.status_code == 200) {
- if (total == io.content_length || io.content_length == 0) {
+ if (io.received == io.content_length || io.content_length == 0) {
fprintf(stderr, " done\n");
- } else if (io.content_length != total) {
+ } else if (io.content_length != io.received) {
fprintf(stderr, "failed (%zu bytes read)\n", total);
io.status_code = 531; /* non official code */
}