Index: src/setup.c
==================================================================
--- src/setup.c
+++ src/setup.c
@@ -917,10 +917,19 @@
@ to this many bytes, uncompressed. If the client requires more data
@ than this, then the client will issue multiple HTTP requests.
@ Values below 1 million are not recommended. 5 million is a
@ reasonable number.
+ @
+ entry_attribute("Download time limit", 11, "max-download-time", "mxdwnt",
+ "30");
+
+ @ Fossil tries to spend less than this many seconds gathering
+ @ the out-bound data of sync, clone, and pull packets.
+ @ If the client request takes longer, a partial reply is given similar
+ @ to the download packet limit. 30s is a reasonable default.
+
@
onoff_attribute(
"Enable hyperlinks for \"nobody\" based on User-Agent and Javascript",
"auto-hyperlink", "autohyperlink", 1);
@ Enable hyperlinks (the equivalent of the "h" permission) for all users
Index: src/xfer.c
==================================================================
--- src/xfer.c
+++ src/xfer.c
@@ -18,10 +18,12 @@
** This file contains code to implement the file transfer protocol.
*/
#include "config.h"
#include "xfer.h"
+#include
+
/*
** This structure holds information about the current state of either
** a client or a server that is participating in xfer.
*/
typedef struct Xfer Xfer;
@@ -40,10 +42,11 @@
int nDeltaRcvd; /* Number of deltas received */
int nDanglingFile; /* Number of dangling deltas received */
int mxSend; /* Stop sending "file" with pOut reaches this size */
u8 syncPrivate; /* True to enable syncing private content */
u8 nextIsPrivate; /* If true, next "file" received is a private */
+ time_t maxTime; /* Time when this transfer should be finished */
};
/*
** The input blob contains a UUID. Convert it into a record ID.
@@ -393,11 +396,12 @@
}
if( uuid_is_shunned(blob_str(pUuid)) ){
blob_reset(&uuid);
return;
}
- if( pXfer->mxSend<=blob_size(pXfer->pOut) ){
+ if( (pXfer->maxTime != -1 && time(NULL) >= pXfer->maxTime) ||
+ pXfer->mxSend<=blob_size(pXfer->pOut) ){
const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n";
blob_appendf(pXfer->pOut, zFormat, pUuid);
pXfer->nIGotSent++;
blob_reset(&uuid);
return;
@@ -867,10 +871,11 @@
}
blob_zero(&xfer.err);
xfer.pIn = &g.cgiIn;
xfer.pOut = cgi_output_blob();
xfer.mxSend = db_get_int("max-download", 5000000);
+ xfer.maxTime = time(NULL) + db_get_int("max-download-time", 30);
g.xferPanic = 1;
db_begin_transaction();
db_multi_exec(
"CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
@@ -1034,11 +1039,12 @@
if( iVers>=3 ){
cgi_set_content_type("application/x-fossil-uncompressed");
}
blob_is_int(&xfer.aToken[2], &seqno);
max = db_int(0, "SELECT max(rid) FROM blob");
- while( xfer.mxSend>blob_size(xfer.pOut) && seqno<=max ){
+ while( xfer.mxSend>blob_size(xfer.pOut) && seqno<=max){
+ if( time(NULL) >= xfer.maxTime ) break;
if( iVers>=3 ){
send_compressed_file(&xfer, seqno);
}else{
send_file(&xfer, seqno, 0, 1);
}
@@ -1328,10 +1334,11 @@
socket_global_init();
memset(&xfer, 0, sizeof(xfer));
xfer.pIn = &recv;
xfer.pOut = &send;
xfer.mxSend = db_get_int("max-upload", 250000);
+ xfer.maxTime = -1;
if( syncFlags & SYNC_PRIVATE ){
g.perm.Private = 1;
xfer.syncPrivate = 1;
}