35#include <sys/socket.h>
50#include <netinet/in.h>
93 std::cerr <<
"Version: " <<
VERSION << std::endl
94 <<
"Usage: " <<
progname <<
" [Basic Options] [HTTP Options]" << std::endl
97 <<
" -s | --quiet Silent. Do not print response message to stdout." << std::endl
98 <<
" -v | --verbose Verbose debugging. Repeat (-vv) to increase output level." << std::endl
99 <<
" Levels:" << std::endl
100 <<
" 1 - Print outgoing request message to stderr." << std::endl
101 <<
" 2 - Print action trace to stderr." << std::endl
102 <<
" --help Display this help text." << std::endl
107 <<
"HTTP Options:" << std::endl
108 <<
" -a Do NOT include Accept: header." << std::endl
109 <<
" -A User-Agent: header. Use \"\" to omit." << std::endl
110 <<
" -H 'string' Extra headers to send. Supports '\\\\', '\\n', '\\r' and '\\t'." << std::endl
111 <<
" -i IMS If-Modified-Since time (in Epoch seconds)." << std::endl
112 <<
" -j hosthdr Host header content" << std::endl
113 <<
" -k Keep the connection active. Default is to do only one request then close." << std::endl
114 <<
" -m method Request method, default is GET." << std::endl
116 <<
" -n Proxy Negotiate(Kerberos) authentication" << std::endl
117 <<
" -N WWW Negotiate(Kerberos) authentication" << std::endl
119 <<
" -P file Send content from the named file as request payload" << std::endl
120 <<
" -r Force cache to reload URL" << std::endl
121 <<
" -t count Trace count cache-hops" << std::endl
122 <<
" -u user Proxy authentication username" << std::endl
123 <<
" -U user WWW authentication username" << std::endl
124 <<
" -V version HTTP Version. Use '-' for HTTP/0.9 omitted case" << std::endl
125 <<
" -w password Proxy authentication password" << std::endl
126 <<
" -W password WWW authentication password" << std::endl
137 unsigned char *p, *d;
139 d = p =
reinterpret_cast<unsigned char *
>(buf);
141 while (
auto ch = *p) {
161 debugVerbose(1,
"Warning: unsupported shell code '\\" << ch <<
"'");
189 void commit(std::ostream &os);
205 std::cerr <<
"ERROR: " <<
destination <<
" password missing\n";
212 const auto buf =
new char[bcapacity];
219 assert(bsize <= bcapacity);
221 os <<
header <<
": Basic ";
222 os.write(buf, bsize);
234 int len, bytesWritten;
235 bool to_stdout, reload;
237 int opt_noaccept = 0;
239 int www_neg = 0, proxy_neg = 0;
243 char *extra_hdrs =
nullptr;
244 const char *method =
"GET";
247 int max_forwards = -1;
249 const char *host =
nullptr;
251 const char *useragent =
nullptr;
258 if (argc < 2 || argv[argc-1][0] ==
'-') {
260 }
else if (argc >= 2) {
261 strncpy(url, argv[argc - 1],
sizeof(url));
262 url[
sizeof(url) - 1] =
'\0';
265 const char *
shortOpStr =
"aA:h:j:V:l:P:i:km:nNp:rsvt:H:T:u:U:w:W:?";
268 static struct option basicOptions[] = {
270 {
"help", no_argument,
nullptr,
'?'},
271 {
"verbose", no_argument,
nullptr,
'v'},
272 {
"quiet", no_argument,
nullptr,
's'},
273 {
"host", required_argument,
nullptr,
'h'},
274 {
"local", required_argument,
nullptr,
'l'},
275 {
"port", required_argument,
nullptr,
'p'},
276 {
"ping", no_argument,
nullptr,
'\1'},
277 {
"https", no_argument,
nullptr,
'\3'},
278 {
nullptr, 0,
nullptr, 0}
282 while ((c = getopt_long(argc, argv,
shortOpStr, basicOptions, &optIndex)) != -1) {
345 ims = (time_t) atoi(
optarg);
354 max_forwards = atoi(
optarg);
360 std::cerr <<
"ERROR: multiple -H options not supported. Discarding previous value." << std::endl;
392 std::cerr <<
"ERROR: Negotiate authentication not supported." << std::endl;
401 std::cerr <<
"ERROR: Negotiate authentication not supported." << std::endl;
420 std::cerr <<
"ERROR: Proxy authentication password (-w) is given, but username (-u) is missing\n";
424 std::cerr <<
"ERROR: WWW authentication password (-W) is given, but username (-U) is missing\n";
431 WSAStartup(2, &wsaData);
436 const char *pathPassword =
nullptr;
437 if (strncmp(url,
"mgr:", 4) == 0) {
441 if (
const auto at = strrchr(url,
'@')) {
443 std::cerr <<
"ERROR: Embedding a password in a cache manager command requires " <<
444 "providing a username with -U: mgr:" << t << std::endl;
448 pathPassword = at + 1;
458 std::cerr <<
"ERROR: can't open file (" <<
xstrerr(xerrno) <<
")" << std::endl;
467 std::cerr <<
"ERROR: can't identify length of file (" <<
xstrerr(xerrno) <<
")" << std::endl;
472 char *newhost = strstr(url,
"://");
477 t = newhost + strcspn(newhost,
"@/?");
480 t = newhost + strcspn(newhost,
"@/?");
487 std::stringstream msg;
491 msg << method <<
" " << url <<
"\r\n";
496 << (versionImpliesHttp ?
"HTTP/" :
"") <<
version
500 msg <<
"Host: " << host <<
"\r\n";
504 msg <<
"User-Agent: squidclient/" <<
VERSION <<
"\r\n";
505 }
else if (useragent[0] !=
'\0') {
506 msg <<
"User-Agent: " << useragent <<
"\r\n";
510 msg <<
"Cache-Control: no-cache\r\n";
513 msg <<
"Content-length: " <<
sb.st_size <<
"\r\n";
515 if (opt_noaccept == 0) {
516 msg <<
"Accept: */*\r\n";
521 if (max_forwards > -1) {
522 msg <<
"Max-Forwards: " << max_forwards <<
"\r\n";
536 const char *token = GSSAPI_token(host);
537 msg <<
"Proxy-Authorization: Negotiate " << token <<
"\r\n";
540 std::cerr <<
"ERROR: server host missing" << std::endl;
545 msg <<
"Proxy-Authorization: Negotiate " << token <<
"\r\n";
548 std::cerr <<
"ERROR: proxy server host missing" << std::endl;
553 if (strcmp(
version,
"1.0") == 0 && keep_alive)
554 msg <<
"Connection: keep-alive\r\n";
558 msg <<
"Connection: close\r\n";
568 const auto messageHeader = msg.str();
569 debugVerbose(1,
"Request:" << std::endl << messageHeader << std::endl <<
".");
573 for (uint32_t i = 0; loops == 0 || i < loops; ++i) {
581 bytesWritten =
Transport::Write(messageHeader.data(), messageHeader.length());
583 if (bytesWritten < 0) {
584 std::cerr <<
"ERROR: write" << std::endl;
586 }
else if (
static_cast<size_t>(bytesWritten) != messageHeader.length()) {
587 std::cerr <<
"ERROR: Failed to send the following request: " << std::endl
588 << messageHeader << std::endl;
596 if ((x = lseek(
put_fd, 0, SEEK_SET)) < 0) {
598 std::cerr <<
"ERROR: lseek: " <<
xstrerr(xerrno) << std::endl;
600 }
else while ((x = read(
put_fd, buf,
sizeof(buf))) > 0) {
611 std::cerr <<
"ERROR: Cannot send file." << std::endl;
624 if (to_stdout && fwrite(buf, len, 1, stdout) != 1) {
626 std::cerr <<
"ERROR: writing to stdout: " <<
xstrerr(xerrno) << std::endl;
633 std::cerr <<
"- Peer has closed the TLS connection" << std::endl;
634 }
else if (!gnutls_error_is_fatal(len)) {
635 std::cerr <<
"WARNING: " << gnutls_strerror(len) << std::endl;
637 std::cerr <<
"ERROR: " << gnutls_strerror(len) << std::endl;
662 std::cerr <<
"SIGPIPE received." << std::endl;
672 sigemptyset(&sa.sa_mask);
674 if (sigaction(SIGPIPE, &sa,
nullptr) < 0) {
675 std::cerr <<
"ERROR: Cannot set PIPE signal." << std::endl;
#define debugVerbose(LEVEL, MESSAGE)
display debug messages at varying verbosity levels
static void Win32SockCleanup(void)
void base64_encode_init(struct base64_encode_ctx *ctx)
size_t base64_encode_update(struct base64_encode_ctx *ctx, char *dst, size_t length, const uint8_t *src)
size_t base64_encode_final(struct base64_encode_ctx *ctx, char *dst)
#define base64_encode_len(length)
[Proxy-]Authorization header producer
const char * user
user name to encode and send
std::string destination
used when describing password
std::string header
HTTP header name to send.
void commit(std::ostream &os)
finalizes and writes the right HTTP header to the given stream
Authorization(const char *aHeader, const char *aDestination)
const char * password
user password to encode and send
void usage()
display Ping Options command line help to stderr
bool parseCommandOpts(int argc, char *argv[], int c, int &optIndex)
int ioTimeout
I/O operation timeout.
void usage()
display Transport Options command line help to stderr
bool parseCommandOpts(int argc, char *argv[], int c, int &optIndex)
static fde * Table
global table of FD and their state.
static const char * shortOpStr
void ProbeTransport(void)
Probe to discover IPv6 capabilities.
bool LoopDone(int i)
whether ping loop is completed at the given iteration.
uint32_t Init()
initialize the squidclient ping mode
void TimerStop(size_t fsize)
void DisplayStats()
display summary of ping data collected
const char * FormatRfc1123(time_t)
ssize_t Read(void *buf, size_t len)
void ShutdownTls()
De-initialize TLS library environment when necessary.
ssize_t Write(const void *buf, size_t len)
bool Connect()
locate and connect to the configured server
void CloseConnection()
close the current connection
static void usage(const char *progname)
Parameters scParams
global squidcleint parameters
int main(int argc, char *argv[])
static void shellUnescape(char *buf)
static void set_our_signal(void)
void pipe_handler(int sig)
static Authorization OriginAuthorization("Authorization", "origin server")
static Authorization ProxyAuthorization("Proxy-Authorization", "proxy")
const char * xstrerr(int error)