mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-28 21:28:55 +00:00
Add pause/resume support to libxpnet's ftp and download impls.
b = 67247 r = ssu sr = mscott
This commit is contained in:
parent
136c629c2f
commit
882fe0046f
@ -32,8 +32,10 @@ DIRS = src
|
||||
|
||||
# solaris tbox doesn't like this!
|
||||
ifneq (,$(filter Linux,$(OS_ARCH)))
|
||||
ifdef ENABLE_TESTS
|
||||
DIRS += test
|
||||
endif
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
@ -24,7 +24,11 @@
|
||||
|
||||
DEPTH=..\..\..
|
||||
|
||||
DIRS=src test
|
||||
DIRS=src \
|
||||
!if !defined(DISABLE_TESTS)
|
||||
test \
|
||||
!endif
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
|
@ -121,8 +121,36 @@ nsFTPConn::Open(char *aHost)
|
||||
}
|
||||
|
||||
int
|
||||
nsFTPConn::Get(char *aSrvPath, char *aLoclPath, int aType, int aOvWrite,
|
||||
FTPGetCB aCBFunc)
|
||||
nsFTPConn::ResumeOrGet(char *aSrvPath, char *aLoclPath, int aType,
|
||||
int aOvWrite, FTPGetCB aCBFunc)
|
||||
{
|
||||
struct stat stbuf;
|
||||
int err = OK;
|
||||
int resPos = 0;
|
||||
|
||||
if (!aLoclPath)
|
||||
return E_PARAM;
|
||||
|
||||
/* stat local file */
|
||||
err = stat(aLoclPath, &stbuf);
|
||||
if (err == 0)
|
||||
resPos = stbuf.st_size;
|
||||
|
||||
return Get(aSrvPath, aLoclPath, aType, resPos, aOvWrite, aCBFunc);
|
||||
}
|
||||
|
||||
int
|
||||
nsFTPConn::Get(char *aSrvPath, char *aLoclPath, int aType,
|
||||
int aOvWrite, FTPGetCB aCBFunc)
|
||||
{
|
||||
// deprecated API; wrapper for backwards compatibility
|
||||
|
||||
return ResumeOrGet(aSrvPath, aLoclPath, aType, aOvWrite, aCBFunc);
|
||||
}
|
||||
|
||||
int
|
||||
nsFTPConn::Get(char *aSrvPath, char *aLoclPath, int aType, int aResumePos,
|
||||
int aOvWrite, FTPGetCB aCBFunc)
|
||||
{
|
||||
struct stat dummy;
|
||||
int err = OK, wrote = 0, totBytesRd = 0;
|
||||
@ -155,6 +183,13 @@ nsFTPConn::Get(char *aSrvPath, char *aLoclPath, int aType, int aOvWrite,
|
||||
if (err == OK && (resp[0] == '2'))
|
||||
fileSize = atoi(&resp[4]);
|
||||
|
||||
if (aResumePos > 0)
|
||||
{
|
||||
/* issue restart command */
|
||||
sprintf(cmd, "REST %d\r\n", aResumePos);
|
||||
ERR_CHECK(IssueCmd(cmd, resp, kRespBufSize, mCntlSock));
|
||||
}
|
||||
|
||||
/* issue RETR command on control connection */
|
||||
sprintf(cmd, "RETR %s\r\n", aSrvPath);
|
||||
ERR_CHECK(IssueCmd(cmd, resp, kRespBufSize, mCntlSock));
|
||||
@ -164,11 +199,22 @@ nsFTPConn::Get(char *aSrvPath, char *aLoclPath, int aType, int aOvWrite,
|
||||
ERR_CHECK(mDataSock->SrvAccept());
|
||||
|
||||
/* initialize locl file */
|
||||
if (!(loclfd = fopen(aLoclPath, aType==BINARY ? "wb" : "w")) ||
|
||||
(fseek(loclfd, 0, SEEK_SET) != 0))
|
||||
if (aResumePos <= 0)
|
||||
{
|
||||
err = E_LOCL_INIT;
|
||||
goto BAIL;
|
||||
if (!(loclfd = fopen(aLoclPath, aType==BINARY ? "w+b" : "w+")))
|
||||
{
|
||||
err = E_LOCL_INIT;
|
||||
goto BAIL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(loclfd = fopen(aLoclPath, aType==BINARY ? "r+b" : "r+")) ||
|
||||
(fseek(loclfd, aResumePos, SEEK_SET) != 0))
|
||||
{
|
||||
err = E_LOCL_INIT;
|
||||
goto BAIL;
|
||||
}
|
||||
}
|
||||
|
||||
totBytesRd = 0;
|
||||
@ -296,6 +342,27 @@ nsFTPConn::IssueCmd(char *aCmd, char *aResp, int aRespSize, nsSocket *aSock)
|
||||
}
|
||||
}
|
||||
|
||||
/* restart command case */
|
||||
else if (strncmp(aCmd, "REST", 4) == 0)
|
||||
{
|
||||
switch (*aResp)
|
||||
{
|
||||
case '1':
|
||||
case '2':
|
||||
err = E_CMD_ERR;
|
||||
break;
|
||||
case '3':
|
||||
break;
|
||||
case '4':
|
||||
case '5':
|
||||
err = E_CMD_FAIL;
|
||||
break;
|
||||
default:
|
||||
err = E_CMD_UNEXPECTED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* regular interpretation of err codes */
|
||||
else
|
||||
{
|
||||
|
@ -52,8 +52,12 @@ public:
|
||||
|
||||
int Open();
|
||||
int Open(char *aHost);
|
||||
int Get(char *aSrvPath, char *aLoclPath, int aType, int aOvWrite,
|
||||
FTPGetCB aCBFunc);
|
||||
int ResumeOrGet(char *aSrvPath, char *aLoclPath, int aType,
|
||||
int aOvWrite, FTPGetCB aCBFunc);
|
||||
int Get(char *aSrvPath, char *aLoclPath, int aType,
|
||||
int aOvWrite, FTPGetCB aCBFunc);
|
||||
int Get(char *aSrvPath, char *aLoclPath, int aType, int aResumePos,
|
||||
int aOvWrite, FTPGetCB aCBFunc);
|
||||
int Close();
|
||||
|
||||
/*--------------------------------------------------------------------*
|
||||
|
@ -112,7 +112,36 @@ nsHTTPConn::Open()
|
||||
}
|
||||
|
||||
int
|
||||
nsHTTPConn::ResumeOrGet(HTTPGetCB aCallback, char *aDestFile)
|
||||
{
|
||||
struct stat stbuf;
|
||||
int rv = 0;
|
||||
int resPos = 0;
|
||||
|
||||
if (!aDestFile)
|
||||
return E_PARAM;
|
||||
|
||||
/* stat local file */
|
||||
rv = stat(aDestFile, &stbuf);
|
||||
if (rv == 0)
|
||||
resPos = stbuf.st_size;
|
||||
|
||||
return Get(aCallback, aDestFile, resPos);
|
||||
|
||||
// XXX TO DO:
|
||||
// XXX handle proxies
|
||||
}
|
||||
|
||||
int
|
||||
nsHTTPConn::Get(HTTPGetCB aCallback, char *aDestFile)
|
||||
{
|
||||
// deprecated API; wrapper for backwards compatibility
|
||||
|
||||
return ResumeOrGet(aCallback, aDestFile);
|
||||
}
|
||||
|
||||
int
|
||||
nsHTTPConn::Get(HTTPGetCB aCallback, char *aDestFile, int aResumePos)
|
||||
{
|
||||
int rv;
|
||||
char *pathToUse;
|
||||
@ -136,11 +165,11 @@ nsHTTPConn::Get(HTTPGetCB aCallback, char *aDestFile)
|
||||
}
|
||||
|
||||
// issue request
|
||||
rv = Request();
|
||||
rv = Request(aResumePos);
|
||||
|
||||
// recv response
|
||||
if (rv == OK)
|
||||
rv = Response(aCallback, aDestFile);
|
||||
rv = Response(aCallback, aDestFile, aResumePos);
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -169,7 +198,7 @@ nsHTTPConn::SetProxyInfo(char *aProxiedURL, char *aProxyUser,
|
||||
}
|
||||
|
||||
int
|
||||
nsHTTPConn::Request()
|
||||
nsHTTPConn::Request(int aResumePos)
|
||||
{
|
||||
char req[kReqBufSize];
|
||||
char hdr[kHdrBufSize];
|
||||
@ -249,6 +278,13 @@ nsHTTPConn::Request()
|
||||
|
||||
}
|
||||
|
||||
// byte range support
|
||||
if (aResumePos > 0)
|
||||
{
|
||||
sprintf(hdr, "Range: bytes=%d-%s", aResumePos, kCRLF);
|
||||
strcat(req, hdr);
|
||||
}
|
||||
|
||||
// headers all done so indicate
|
||||
strcat(req, kCRLF);
|
||||
|
||||
@ -264,7 +300,7 @@ nsHTTPConn::Request()
|
||||
}
|
||||
|
||||
int
|
||||
nsHTTPConn::Response(HTTPGetCB aCallback, char *aDestFile)
|
||||
nsHTTPConn::Response(HTTPGetCB aCallback, char *aDestFile, int aResumePos)
|
||||
{
|
||||
// NOTE: overwrites dest file if it already exists
|
||||
|
||||
@ -279,9 +315,24 @@ nsHTTPConn::Response(HTTPGetCB aCallback, char *aDestFile)
|
||||
return E_PARAM;
|
||||
|
||||
// open dest file
|
||||
destFd = fopen(aDestFile, "w+b");
|
||||
if (!destFd)
|
||||
return E_OPEN_FILE;
|
||||
if (aResumePos > 0)
|
||||
{
|
||||
destFd = fopen(aDestFile, "r+b");
|
||||
if (!destFd)
|
||||
return E_OPEN_FILE;
|
||||
|
||||
if (fseek(destFd, aResumePos, SEEK_SET) != 0)
|
||||
{
|
||||
fclose(destFd);
|
||||
return E_SEEK_FILE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
destFd = fopen(aDestFile, "w+b");
|
||||
if (!destFd)
|
||||
return E_OPEN_FILE;
|
||||
}
|
||||
|
||||
// iteratively recv response
|
||||
do
|
||||
@ -324,9 +375,10 @@ nsHTTPConn::Response(HTTPGetCB aCallback, char *aDestFile)
|
||||
|
||||
if (fwriteLen > 0)
|
||||
bytesWritten += fwriteLen;
|
||||
if (aCallback && (aCallback(bytesWritten, expectedSize) == E_USER_CANCEL))
|
||||
rv = E_USER_CANCEL; /* we want to ignore all errors returned
|
||||
* from aCallback() except E_USER_CANCEL */
|
||||
if (aCallback &&
|
||||
(aCallback(bytesWritten, expectedSize) == E_USER_CANCEL))
|
||||
rv = E_USER_CANCEL; // we want to ignore all errors returned
|
||||
// from aCallback() except E_USER_CANCEL
|
||||
|
||||
} while (rv == nsSocket::E_READ_MORE || rv == nsSocket::OK);
|
||||
|
||||
|
@ -37,7 +37,9 @@ public:
|
||||
~nsHTTPConn();
|
||||
|
||||
int Open();
|
||||
int ResumeOrGet(HTTPGetCB aCallback, char *aDestFile);
|
||||
int Get(HTTPGetCB aCallback, char *aDestFile);
|
||||
int Get(HTTPGetCB aCallback, char *aDestFile, int aResumePos);
|
||||
int Close();
|
||||
|
||||
void SetProxyInfo(char *aProxiedURL, char *aProxyUser,
|
||||
@ -54,12 +56,13 @@ public:
|
||||
E_REQ_INCOMPLETE = -804,
|
||||
E_B64_ENCODE = -805,
|
||||
E_OPEN_FILE = -806,
|
||||
E_SEEK_FILE = -807,
|
||||
E_USER_CANCEL = -813
|
||||
};
|
||||
|
||||
private:
|
||||
int Request();
|
||||
int Response(HTTPGetCB aCallback, char *aDestFile);
|
||||
int Request(int aResumePos);
|
||||
int Response(HTTPGetCB aCallback, char *aDestFile, int aResumePos);
|
||||
void ParseContentLength(const char *aBuf, int *aLength);
|
||||
int Base64Encode(const unsigned char *in_str, int in_len,
|
||||
char *out_str, int out_len);
|
||||
|
@ -64,8 +64,9 @@ spew(char *funcName, int rv)
|
||||
void
|
||||
usage(char *prog)
|
||||
{
|
||||
fprintf(stderr, "usage: %s <URL> [ProxyServer ", prog);
|
||||
fprintf(stderr, "ProxyPort [ProxyUserName ProxyPassword]\n");
|
||||
fprintf(stderr, "usage: %s <URL>\n\t\t[<ProxyServer> ", prog);
|
||||
fprintf(stderr, "<ProxyPort> [<ProxyUserName> <ProxyPassword>]]\n");
|
||||
fprintf(stderr, "\t\t[-r<ResumePos> or -rg]\n");
|
||||
|
||||
#ifdef macintosh
|
||||
int fin = getchar();
|
||||
@ -77,10 +78,11 @@ main(int argc, char **argv)
|
||||
{
|
||||
char *proxyUser = 0, *proxyPswd = 0;
|
||||
char proxyURL[kProxySrvrLen];
|
||||
int rv = 0;
|
||||
int rv = 0, resPos = 0;
|
||||
time_t startTime, endTime;
|
||||
double dlTime = 0; /* download time */
|
||||
float dlRate = 0; /* download rate */
|
||||
int bResumeOrGet = 0;
|
||||
|
||||
#ifdef macintosh
|
||||
argc = ccommand(&argv);
|
||||
@ -92,6 +94,25 @@ main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* get resume pos if -r arg passed in */
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
/* resume or get */
|
||||
if (strncmp(argv[i], "-rg", 3) == 0)
|
||||
{
|
||||
bResumeOrGet = 1;
|
||||
}
|
||||
|
||||
/* resume from pos */
|
||||
else if (strncmp(argv[i], "-r", 2) == 0)
|
||||
{
|
||||
resPos = atoi(argv[i] + 2);
|
||||
printf("resPos = %d\n", resPos);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* has a proxy server been specified? */
|
||||
if (argc >= 4)
|
||||
{
|
||||
@ -117,7 +138,14 @@ main(int argc, char **argv)
|
||||
spew("nsHTTPConn::Open", rv);
|
||||
|
||||
startTime = time(NULL);
|
||||
rv = conn->Get(ProgressCB, NULL); // use leaf from URL
|
||||
if (bResumeOrGet)
|
||||
{
|
||||
rv = conn->ResumeOrGet(ProgressCB, NULL); // use leaf from URL
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = conn->Get(ProgressCB, NULL, resPos); // use leaf from URL
|
||||
}
|
||||
endTime = time(NULL);
|
||||
printf("\n"); // newline after progress completes
|
||||
spew("nsHTTPConn::Get", rv);
|
||||
@ -136,7 +164,14 @@ main(int argc, char **argv)
|
||||
spew("nsHTTPConn::Open", rv);
|
||||
|
||||
startTime = time(NULL);
|
||||
rv = conn->Get(ProgressCB, NULL);
|
||||
if (bResumeOrGet)
|
||||
{
|
||||
rv = conn->ResumeOrGet(ProgressCB, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = conn->Get(ProgressCB, NULL, resPos);
|
||||
}
|
||||
endTime = time(NULL);
|
||||
printf("\n"); // newline after progress completes
|
||||
spew("nsHTTPConn::Get", rv);
|
||||
@ -162,7 +197,16 @@ main(int argc, char **argv)
|
||||
if (strrchr(path, '/') != (path + strlen(path)))
|
||||
file = strrchr(path, '/') + 1; // set to leaf name
|
||||
startTime = time(NULL);
|
||||
rv = conn->Get(path, file, nsFTPConn::BINARY, 1, ProgressCB);
|
||||
if (bResumeOrGet)
|
||||
{
|
||||
rv = conn->ResumeOrGet(path, file, nsFTPConn::BINARY, 1,
|
||||
ProgressCB);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = conn->Get(path, file, nsFTPConn::BINARY, resPos, 1,
|
||||
ProgressCB);
|
||||
}
|
||||
endTime = time(NULL);
|
||||
printf("\n"); // newline after progress completes
|
||||
spew("nsFTPConn::Get", rv);
|
||||
|
Loading…
x
Reference in New Issue
Block a user