mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-06 17:18:32 +00:00
Base64 code (and the MIT copyright) moved to http.c
FTP STORe and APPEnd added. FTP proxy support added (untested).
This commit is contained in:
parent
e1b7cfe2bf
commit
f62e5228fd
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=37608
|
@ -1,90 +0,0 @@
|
|||
/*-
|
||||
* Copyright 1997 Massachusetts Institute of Technology
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby
|
||||
* granted, provided that both the above copyright notice and this
|
||||
* permission notice appear in all copies, that both the above
|
||||
* copyright notice and this permission notice appear in all
|
||||
* supporting documentation, and that the name of M.I.T. not be used
|
||||
* in advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission. M.I.T. makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
|
||||
* ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
|
||||
* SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: util.c,v 1.6 1998/02/20 05:08:53 jb Exp $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* Not much left of the original MIT code, but it's still derived from it
|
||||
* so I'll keep their copyright. This is taken from util.c in MIT fetch.
|
||||
*
|
||||
* -- DES 1998/05/22
|
||||
*/
|
||||
|
||||
/*
|
||||
* Implement the `base64' encoding as described in RFC 1521.
|
||||
*/
|
||||
static const char base64[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
int
|
||||
fprint64(FILE *f, const unsigned char *buf)
|
||||
{
|
||||
int len = 0, l = 0;
|
||||
unsigned int tmp;
|
||||
|
||||
while (buf[len])
|
||||
len++;
|
||||
|
||||
while (len >= 3) {
|
||||
tmp = buf[0] << 16 | buf[1] << 8 | buf[2];
|
||||
fprintf(f, "%c%c%c%c",
|
||||
base64[(tmp >> 18) & 077],
|
||||
base64[(tmp >> 12) & 077],
|
||||
base64[(tmp >> 6) & 077],
|
||||
base64[tmp & 077]);
|
||||
len -= 3;
|
||||
buf += 3;
|
||||
l += 4;
|
||||
}
|
||||
|
||||
/* RFC 1521 enumerates these three possibilities... */
|
||||
switch(len) {
|
||||
case 2:
|
||||
tmp = buf[0] << 16 | buf[1] << 8;
|
||||
fprintf(f, "%c%c%c=",
|
||||
base64[(tmp >> 18) & 077],
|
||||
base64[(tmp >> 12) & 077],
|
||||
base64[(tmp >> 6) & 077]);
|
||||
l += 4;
|
||||
break;
|
||||
case 1:
|
||||
tmp = buf[0] << 16;
|
||||
fprintf(f, "%c%c==",
|
||||
base64[(tmp >> 18) & 077],
|
||||
base64[(tmp >> 12) & 077]);
|
||||
l += 4;
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
|
@ -25,7 +25,7 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: ftp.c,v 1.1.1.1 1998/07/09 16:52:42 des Exp $
|
||||
* $Id: ftp.c,v 1.3 1998/07/11 21:29:08 des Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -190,10 +190,10 @@ _ftp_cmd(FILE *f, char *fmt, ...)
|
|||
}
|
||||
|
||||
/*
|
||||
* Retrieve file
|
||||
* Transfer file
|
||||
*/
|
||||
static FILE *
|
||||
_ftp_retrieve(FILE *cf, char *file, int pasv)
|
||||
_ftp_transfer(FILE *cf, char *oper, char *file, char *mode, int pasv)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
int sd = -1, l;
|
||||
|
@ -252,7 +252,7 @@ _ftp_retrieve(FILE *cf, char *file, int pasv)
|
|||
goto sysouch;
|
||||
|
||||
/* make the server initiate the transfer */
|
||||
if (_ftp_cmd(cf, "RETR %s" ENDL, s) != FTP_OPEN_DATA_CONNECTION)
|
||||
if (_ftp_cmd(cf, "%s %s" ENDL, oper, s) != FTP_OPEN_DATA_CONNECTION)
|
||||
goto ouch;
|
||||
|
||||
} else {
|
||||
|
@ -281,7 +281,7 @@ _ftp_retrieve(FILE *cf, char *file, int pasv)
|
|||
goto ouch;
|
||||
|
||||
/* make the server initiate the transfer */
|
||||
if (_ftp_cmd(cf, "RETR %s" ENDL, s) != FTP_OPEN_DATA_CONNECTION)
|
||||
if (_ftp_cmd(cf, "%s %s" ENDL, oper, s) != FTP_OPEN_DATA_CONNECTION)
|
||||
goto ouch;
|
||||
|
||||
/* accept the incoming connection and go to town */
|
||||
|
@ -291,7 +291,7 @@ _ftp_retrieve(FILE *cf, char *file, int pasv)
|
|||
sd = d;
|
||||
}
|
||||
|
||||
if ((df = fdopen(sd, "r")) == NULL)
|
||||
if ((df = fdopen(sd, mode)) == NULL)
|
||||
goto sysouch;
|
||||
return df;
|
||||
|
||||
|
@ -302,34 +302,39 @@ _ftp_retrieve(FILE *cf, char *file, int pasv)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Store file
|
||||
*/
|
||||
static FILE *
|
||||
_ftp_store(FILE *cf, char *file, int pasv)
|
||||
{
|
||||
fprintf(stderr, "_ftp_store: not implemented yet.\n");
|
||||
|
||||
cf = cf;
|
||||
file = file;
|
||||
pasv = pasv;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Log on to FTP server
|
||||
*/
|
||||
static FILE *
|
||||
_ftp_connect(char *host, int port, char *user, char *pwd)
|
||||
{
|
||||
int sd, e;
|
||||
int sd, e, pp = FTP_DEFAULT_PORT;
|
||||
char *p, *q;
|
||||
FILE *f;
|
||||
|
||||
/* establish control connection */
|
||||
if ((sd = fetchConnect(host, port)) < 0) {
|
||||
/* check for proxy */
|
||||
if ((p = getenv("FTP_PROXY")) != NULL) {
|
||||
if ((q = strchr(p, ':')) != NULL) {
|
||||
/* XXX check that it's a valid number */
|
||||
pp = atoi(q+1);
|
||||
}
|
||||
if (q)
|
||||
*q = 0;
|
||||
sd = fetchConnect(p, pp);
|
||||
if (q)
|
||||
*q = ':';
|
||||
} else {
|
||||
/* no proxy, go straight to target */
|
||||
sd = fetchConnect(host, port);
|
||||
}
|
||||
|
||||
/* check connection */
|
||||
if (sd < 0) {
|
||||
_ftp_syserr();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* streams make life easier */
|
||||
if ((f = fdopen(sd, "r+")) == NULL) {
|
||||
_ftp_syserr();
|
||||
goto ouch;
|
||||
|
@ -340,20 +345,32 @@ _ftp_connect(char *host, int port, char *user, char *pwd)
|
|||
goto fouch;
|
||||
|
||||
/* send user name and password */
|
||||
e = _ftp_cmd(f, "USER %s" ENDL, user);
|
||||
if (e == FTP_NEED_PASSWORD) /* server requested a password */
|
||||
if (!user || !*user)
|
||||
user = FTP_ANONYMOUS_USER;
|
||||
e = p ? _ftp_cmd(f, "USER %s@%s@%d" ENDL, user, host, port)
|
||||
: _ftp_cmd(f, "USER %s" ENDL, user);
|
||||
|
||||
/* did the server request a password? */
|
||||
if (e == FTP_NEED_PASSWORD) {
|
||||
if (!pwd || !*pwd)
|
||||
pwd = FTP_ANONYMOUS_PASSWORD;
|
||||
e = _ftp_cmd(f, "PASS %s" ENDL, pwd);
|
||||
if (e == FTP_NEED_ACCOUNT) /* server requested an account */
|
||||
}
|
||||
|
||||
/* did the server request an account? */
|
||||
if (e == FTP_NEED_ACCOUNT)
|
||||
/* help! */ ;
|
||||
if (e != FTP_LOGGED_IN) /* won't let us near the WaReZ */
|
||||
|
||||
/* we should be done by now */
|
||||
if (e != FTP_LOGGED_IN)
|
||||
goto fouch;
|
||||
|
||||
/* might as well select mode and type at once */
|
||||
#ifdef FTP_FORCE_STREAM_MODE
|
||||
if (_ftp_cmd(f, "MODE S" ENDL) != FTP_OK)
|
||||
if (_ftp_cmd(f, "MODE S" ENDL) != FTP_OK) /* default is S */
|
||||
goto ouch;
|
||||
#endif
|
||||
if (_ftp_cmd(f, "TYPE I" ENDL) != FTP_OK)
|
||||
if (_ftp_cmd(f, "TYPE I" ENDL) != FTP_OK) /* default is A */
|
||||
goto ouch;
|
||||
|
||||
/* done */
|
||||
|
@ -390,19 +407,15 @@ _ftp_isconnected(url_t *url)
|
|||
&& (url->port == cached_host.port));
|
||||
}
|
||||
|
||||
FILE *
|
||||
fetchGetFTP(url_t *url, char *flags)
|
||||
/*
|
||||
* FTP session
|
||||
*/
|
||||
static FILE *
|
||||
fetchXxxFTP(url_t *url, char *oper, char *mode, char *flags)
|
||||
{
|
||||
FILE *cf = NULL;
|
||||
int e;
|
||||
|
||||
#ifdef DEFAULT_TO_ANONYMOUS
|
||||
if (!url->user[0]) {
|
||||
strcpy(url->user, FTP_ANONYMOUS_USER);
|
||||
strcpy(url->pwd, FTP_ANONYMOUS_PASSWORD);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* set default port */
|
||||
if (!url->port)
|
||||
url->port = FTP_DEFAULT_PORT;
|
||||
|
@ -427,50 +440,22 @@ fetchGetFTP(url_t *url, char *flags)
|
|||
}
|
||||
|
||||
/* initiate the transfer */
|
||||
return _ftp_retrieve(cf, url->doc, (flags && strchr(flags, 'p')));
|
||||
return _ftp_transfer(cf, oper, url->doc, mode, (flags && strchr(flags, 'p')));
|
||||
}
|
||||
|
||||
/*
|
||||
* Upload a file.
|
||||
* Hmmm, that's almost an exact duplicate of the above...
|
||||
* Itsy bitsy teeny weenie
|
||||
*/
|
||||
FILE *
|
||||
fetchGetFTP(url_t *url, char *flags)
|
||||
{
|
||||
return fetchXxxFTP(url, "RETR", "r", flags);
|
||||
}
|
||||
|
||||
FILE *
|
||||
fetchPutFTP(url_t *url, char *flags)
|
||||
{
|
||||
FILE *cf = NULL;
|
||||
int e;
|
||||
|
||||
#ifdef DEFAULT_TO_ANONYMOUS
|
||||
if (!url->user[0]) {
|
||||
strcpy(url->user, FTP_ANONYMOUS_USER);
|
||||
strcpy(url->pwd, FTP_ANONYMOUS_PASSWORD);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* set default port */
|
||||
if (!url->port)
|
||||
url->port = htons(FTP_DEFAULT_PORT);
|
||||
|
||||
/* try to use previously cached connection */
|
||||
if (_ftp_isconnected(url)) {
|
||||
fprintf(cached_socket, "PWD" ENDL);
|
||||
_ftp_chkerr(cached_socket, &e);
|
||||
if (e > 0)
|
||||
cf = cached_socket;
|
||||
}
|
||||
|
||||
/* connect to server */
|
||||
if (!cf) {
|
||||
cf = _ftp_connect(url->host, url->port, url->user, url->pwd);
|
||||
if (!cf)
|
||||
return NULL;
|
||||
if (cached_socket)
|
||||
_ftp_disconnect(cached_socket);
|
||||
cached_socket = cf;
|
||||
memcpy(&cached_host, url, sizeof(url_t));
|
||||
}
|
||||
|
||||
|
||||
/* initiate the transfer */
|
||||
return _ftp_store(cf, url->doc, (flags && strchr(flags, 'p')));
|
||||
if (flags && strchr(flags, 'a'))
|
||||
return fetchXxxFTP(url, "APPE", "w", flags);
|
||||
else return fetchXxxFTP(url, "STOR", "w", flags);
|
||||
}
|
||||
|
|
|
@ -25,9 +25,41 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: http.c,v 1.1.1.1 1998/07/09 16:52:41 des Exp $
|
||||
* $Id: http.c,v 1.3 1998/07/11 21:29:08 des Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* The base64 code in this file is based on code from MIT fetch, which
|
||||
* has the following copyright and license:
|
||||
*
|
||||
*-
|
||||
* Copyright 1997 Massachusetts Institute of Technology
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby
|
||||
* granted, provided that both the above copyright notice and this
|
||||
* permission notice appear in all copies, that both the above
|
||||
* copyright notice and this permission notice appear in all
|
||||
* supporting documentation, and that the name of M.I.T. not be used
|
||||
* in advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission. M.I.T. makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
|
||||
* ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
|
||||
* SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE. */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/socket.h>
|
||||
|
@ -38,6 +70,7 @@
|
|||
#include <err.h>
|
||||
#include <ctype.h>
|
||||
#include <netdb.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -54,8 +87,6 @@
|
|||
|
||||
extern char *__progname;
|
||||
|
||||
extern int fprint64(FILE *f, const unsigned char *buf);
|
||||
|
||||
#define ENDL "\r\n"
|
||||
|
||||
struct cookie
|
||||
|
@ -71,6 +102,9 @@ struct cookie
|
|||
unsigned b_len, chunksize;
|
||||
};
|
||||
|
||||
/*
|
||||
* Look up error code
|
||||
*/
|
||||
static const char *
|
||||
_http_errstring(int e)
|
||||
{
|
||||
|
@ -82,6 +116,29 @@ _http_errstring(int e)
|
|||
return p->string;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a formatted line; optionally echo to terminal
|
||||
*/
|
||||
static int
|
||||
_http_cmd(FILE *f, char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vfprintf(f, fmt, ap);
|
||||
#ifndef NDEBUG
|
||||
fprintf(stderr, "\033[1m>>> ");
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\033[m");
|
||||
#endif
|
||||
va_end(ap);
|
||||
|
||||
return 0; /* XXX */
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill the input buffer, do chunk decoding on the fly
|
||||
*/
|
||||
static char *
|
||||
_http_fillbuf(struct cookie *c)
|
||||
{
|
||||
|
@ -119,6 +176,9 @@ _http_fillbuf(struct cookie *c)
|
|||
return c->buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read function
|
||||
*/
|
||||
static int
|
||||
_http_readfn(struct cookie *c, char *buf, int len)
|
||||
{
|
||||
|
@ -142,6 +202,9 @@ _http_readfn(struct cookie *c, char *buf, int len)
|
|||
else return pos;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write function
|
||||
*/
|
||||
static int
|
||||
_http_writefn(struct cookie *c, const char *buf, int len)
|
||||
{
|
||||
|
@ -149,6 +212,9 @@ _http_writefn(struct cookie *c, const char *buf, int len)
|
|||
return r ? r : -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close function
|
||||
*/
|
||||
static int
|
||||
_http_closefn(struct cookie *c)
|
||||
{
|
||||
|
@ -157,6 +223,9 @@ _http_closefn(struct cookie *c)
|
|||
return (r == EOF) ? -1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract content type from cookie
|
||||
*/
|
||||
char *
|
||||
fetchContentType(FILE *f)
|
||||
{
|
||||
|
@ -167,6 +236,85 @@ fetchContentType(FILE *f)
|
|||
return f->_cookie ? (((struct cookie *)f->_cookie)->content_type) : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Base64 encoding
|
||||
*/
|
||||
int
|
||||
_http_base64(char *dst, char *src, int l)
|
||||
{
|
||||
static const char base64[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
int t, r = 0;
|
||||
|
||||
while (l >= 3) {
|
||||
t = (src[0] << 16) | (src[1] << 8) | src[2];
|
||||
dst[0] = base64[(t >> 18) & 0x3f];
|
||||
dst[1] = base64[(t >> 12) & 0x3f];
|
||||
dst[2] = base64[(t >> 6) & 0x3f];
|
||||
dst[3] = base64[(t >> 0) & 0x3f];
|
||||
src += 3; l -= 3;
|
||||
dst += 4; r += 4;
|
||||
}
|
||||
|
||||
switch (l) {
|
||||
case 2:
|
||||
t = (src[0] << 16) | (src[1] << 8);
|
||||
dst[0] = base64[(t >> 18) & 0x3f];
|
||||
dst[1] = base64[(t >> 12) & 0x3f];
|
||||
dst[2] = base64[(t >> 6) & 0x3f];
|
||||
dst[3] = '=';
|
||||
dst += 4;
|
||||
r += 4;
|
||||
break;
|
||||
case 1:
|
||||
t = src[0] << 16;
|
||||
dst[0] = base64[(t >> 18) & 0x3f];
|
||||
dst[1] = base64[(t >> 12) & 0x3f];
|
||||
dst[2] = dst[3] = '=';
|
||||
dst += 4;
|
||||
r += 4;
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
|
||||
*dst = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encode username and password
|
||||
*/
|
||||
char *
|
||||
_http_auth(char *usr, char *pwd)
|
||||
{
|
||||
int len, lu, lp;
|
||||
char *str, *s;
|
||||
|
||||
lu = strlen(usr);
|
||||
lp = strlen(pwd);
|
||||
|
||||
len = (lu * 4 + 2) / 3 /* user name, round up */
|
||||
+ 1 /* colon */
|
||||
+ (lp * 4 + 2) / 3 /* password, round up */
|
||||
+ 1; /* null */
|
||||
|
||||
if ((s = str = (char *)malloc(len)) == NULL)
|
||||
return NULL;
|
||||
|
||||
s += _http_base64(s, usr, lu);
|
||||
*s++ = ':';
|
||||
s += _http_base64(s, pwd, lp);
|
||||
*s = 0;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* retrieve a file by HTTP
|
||||
*/
|
||||
FILE *
|
||||
fetchGetHTTP(url_t *URL, char *flags)
|
||||
{
|
||||
|
@ -220,20 +368,20 @@ fetchGetHTTP(url_t *URL, char *flags)
|
|||
c->real_f = f;
|
||||
|
||||
/* send request (proxies require absolute form, so use that) */
|
||||
fprintf(f, "GET http://%s:%d/%s HTTP/1.1" ENDL,
|
||||
URL->host, URL->port, URL->doc);
|
||||
_http_cmd(f, "GET http://%s:%d%s HTTP/1.1" ENDL,
|
||||
URL->host, URL->port, URL->doc);
|
||||
|
||||
/* start sending headers away */
|
||||
if (URL->user[0] || URL->pwd[0]) {
|
||||
fprintf(f, "Authorization: Basic ");
|
||||
fprint64(f, (const unsigned char *)URL->user);
|
||||
fputc(':', f);
|
||||
fprint64(f, (const unsigned char *)URL->pwd);
|
||||
fputs(ENDL, f);
|
||||
char *auth_str = _http_auth(URL->user, URL->pwd);
|
||||
if (!auth_str)
|
||||
goto fouch;
|
||||
_http_cmd(f, "Authorization: Basic %s" ENDL, auth_str);
|
||||
free(auth_str);
|
||||
}
|
||||
fprintf(f, "Host: %s:%d" ENDL, URL->host, URL->port);
|
||||
fprintf(f, "User-Agent: %s " _LIBFETCH_VER ENDL, __progname);
|
||||
fprintf(f, "Connection: close" ENDL ENDL);
|
||||
_http_cmd(f, "Host: %s:%d" ENDL, URL->host, URL->port);
|
||||
_http_cmd(f, "User-Agent: %s " _LIBFETCH_VER ENDL, __progname);
|
||||
_http_cmd(f, "Connection: close" ENDL ENDL);
|
||||
|
||||
/* get response */
|
||||
if ((ln = fgetln(f, &len)) == NULL)
|
||||
|
|
Loading…
Reference in a new issue