Fossil SCM

Add the max-download-time server option that limits the amount of real-time that the server will spend preparing an xfer protocol reply.

drh 2013-01-23 13:24 trunk merge
Commit 769c90a2300cb80bca45074110c083a9b1b622a7
3 files changed +9 +11 -2 +11 -2
--- src/setup.c
+++ src/setup.c
@@ -917,10 +917,19 @@
917917
@ to this many bytes, uncompressed. If the client requires more data
918918
@ than this, then the client will issue multiple HTTP requests.
919919
@ Values below 1 million are not recommended. 5 million is a
920920
@ reasonable number.</p>
921921
922
+ @ <hr />
923
+ entry_attribute("Download time limit", 11, "max-download-time", "mxdwnt",
924
+ "30");
925
+
926
+ @ <p>Fossil tries to spend less than this many seconds gathering
927
+ @ the out-bound data of sync, clone, and pull packets.
928
+ @ If the client request takes longer, a partial reply is given similar
929
+ @ to the download packet limit. 30s is a reasonable default.</p>
930
+
922931
@ <hr />
923932
onoff_attribute(
924933
"Enable hyperlinks for \"nobody\" based on User-Agent and Javascript",
925934
"auto-hyperlink", "autohyperlink", 1);
926935
@ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users
927936
--- src/setup.c
+++ src/setup.c
@@ -917,10 +917,19 @@
917 @ to this many bytes, uncompressed. If the client requires more data
918 @ than this, then the client will issue multiple HTTP requests.
919 @ Values below 1 million are not recommended. 5 million is a
920 @ reasonable number.</p>
921
 
 
 
 
 
 
 
 
 
922 @ <hr />
923 onoff_attribute(
924 "Enable hyperlinks for \"nobody\" based on User-Agent and Javascript",
925 "auto-hyperlink", "autohyperlink", 1);
926 @ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users
927
--- src/setup.c
+++ src/setup.c
@@ -917,10 +917,19 @@
917 @ to this many bytes, uncompressed. If the client requires more data
918 @ than this, then the client will issue multiple HTTP requests.
919 @ Values below 1 million are not recommended. 5 million is a
920 @ reasonable number.</p>
921
922 @ <hr />
923 entry_attribute("Download time limit", 11, "max-download-time", "mxdwnt",
924 "30");
925
926 @ <p>Fossil tries to spend less than this many seconds gathering
927 @ the out-bound data of sync, clone, and pull packets.
928 @ If the client request takes longer, a partial reply is given similar
929 @ to the download packet limit. 30s is a reasonable default.</p>
930
931 @ <hr />
932 onoff_attribute(
933 "Enable hyperlinks for \"nobody\" based on User-Agent and Javascript",
934 "auto-hyperlink", "autohyperlink", 1);
935 @ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users
936
+11 -2
--- src/xfer.c
+++ src/xfer.c
@@ -18,10 +18,12 @@
1818
** This file contains code to implement the file transfer protocol.
1919
*/
2020
#include "config.h"
2121
#include "xfer.h"
2222
23
+#include <time.h>
24
+
2325
/*
2426
** This structure holds information about the current state of either
2527
** a client or a server that is participating in xfer.
2628
*/
2729
typedef struct Xfer Xfer;
@@ -40,10 +42,11 @@
4042
int nDeltaRcvd; /* Number of deltas received */
4143
int nDanglingFile; /* Number of dangling deltas received */
4244
int mxSend; /* Stop sending "file" with pOut reaches this size */
4345
u8 syncPrivate; /* True to enable syncing private content */
4446
u8 nextIsPrivate; /* If true, next "file" received is a private */
47
+ time_t maxTime; /* Time when this transfer should be finished */
4548
};
4649
4750
4851
/*
4952
** The input blob contains a UUID. Convert it into a record ID.
@@ -393,11 +396,12 @@
393396
}
394397
if( uuid_is_shunned(blob_str(pUuid)) ){
395398
blob_reset(&uuid);
396399
return;
397400
}
398
- if( pXfer->mxSend<=blob_size(pXfer->pOut) ){
401
+ if( (pXfer->maxTime != -1 && time(NULL) >= pXfer->maxTime) ||
402
+ pXfer->mxSend<=blob_size(pXfer->pOut) ){
399403
const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n";
400404
blob_appendf(pXfer->pOut, zFormat, pUuid);
401405
pXfer->nIGotSent++;
402406
blob_reset(&uuid);
403407
return;
@@ -867,10 +871,13 @@
867871
}
868872
blob_zero(&xfer.err);
869873
xfer.pIn = &g.cgiIn;
870874
xfer.pOut = cgi_output_blob();
871875
xfer.mxSend = db_get_int("max-download", 5000000);
876
+ xfer.maxTime = db_get_int("max-download-time", 30);
877
+ if( xfer.maxTime<1 ) xfer.maxTime = 1;
878
+ xfer.maxTime += time(NULL);
872879
g.xferPanic = 1;
873880
874881
db_begin_transaction();
875882
db_multi_exec(
876883
"CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
@@ -1034,11 +1041,12 @@
10341041
if( iVers>=3 ){
10351042
cgi_set_content_type("application/x-fossil-uncompressed");
10361043
}
10371044
blob_is_int(&xfer.aToken[2], &seqno);
10381045
max = db_int(0, "SELECT max(rid) FROM blob");
1039
- while( xfer.mxSend>blob_size(xfer.pOut) && seqno<=max ){
1046
+ while( xfer.mxSend>blob_size(xfer.pOut) && seqno<=max){
1047
+ if( time(NULL) >= xfer.maxTime ) break;
10401048
if( iVers>=3 ){
10411049
send_compressed_file(&xfer, seqno);
10421050
}else{
10431051
send_file(&xfer, seqno, 0, 1);
10441052
}
@@ -1328,10 +1336,11 @@
13281336
socket_global_init();
13291337
memset(&xfer, 0, sizeof(xfer));
13301338
xfer.pIn = &recv;
13311339
xfer.pOut = &send;
13321340
xfer.mxSend = db_get_int("max-upload", 250000);
1341
+ xfer.maxTime = -1;
13331342
if( syncFlags & SYNC_PRIVATE ){
13341343
g.perm.Private = 1;
13351344
xfer.syncPrivate = 1;
13361345
}
13371346
13381347
--- src/xfer.c
+++ src/xfer.c
@@ -18,10 +18,12 @@
18 ** This file contains code to implement the file transfer protocol.
19 */
20 #include "config.h"
21 #include "xfer.h"
22
 
 
23 /*
24 ** This structure holds information about the current state of either
25 ** a client or a server that is participating in xfer.
26 */
27 typedef struct Xfer Xfer;
@@ -40,10 +42,11 @@
40 int nDeltaRcvd; /* Number of deltas received */
41 int nDanglingFile; /* Number of dangling deltas received */
42 int mxSend; /* Stop sending "file" with pOut reaches this size */
43 u8 syncPrivate; /* True to enable syncing private content */
44 u8 nextIsPrivate; /* If true, next "file" received is a private */
 
45 };
46
47
48 /*
49 ** The input blob contains a UUID. Convert it into a record ID.
@@ -393,11 +396,12 @@
393 }
394 if( uuid_is_shunned(blob_str(pUuid)) ){
395 blob_reset(&uuid);
396 return;
397 }
398 if( pXfer->mxSend<=blob_size(pXfer->pOut) ){
 
399 const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n";
400 blob_appendf(pXfer->pOut, zFormat, pUuid);
401 pXfer->nIGotSent++;
402 blob_reset(&uuid);
403 return;
@@ -867,10 +871,13 @@
867 }
868 blob_zero(&xfer.err);
869 xfer.pIn = &g.cgiIn;
870 xfer.pOut = cgi_output_blob();
871 xfer.mxSend = db_get_int("max-download", 5000000);
 
 
 
872 g.xferPanic = 1;
873
874 db_begin_transaction();
875 db_multi_exec(
876 "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
@@ -1034,11 +1041,12 @@
1034 if( iVers>=3 ){
1035 cgi_set_content_type("application/x-fossil-uncompressed");
1036 }
1037 blob_is_int(&xfer.aToken[2], &seqno);
1038 max = db_int(0, "SELECT max(rid) FROM blob");
1039 while( xfer.mxSend>blob_size(xfer.pOut) && seqno<=max ){
 
1040 if( iVers>=3 ){
1041 send_compressed_file(&xfer, seqno);
1042 }else{
1043 send_file(&xfer, seqno, 0, 1);
1044 }
@@ -1328,10 +1336,11 @@
1328 socket_global_init();
1329 memset(&xfer, 0, sizeof(xfer));
1330 xfer.pIn = &recv;
1331 xfer.pOut = &send;
1332 xfer.mxSend = db_get_int("max-upload", 250000);
 
1333 if( syncFlags & SYNC_PRIVATE ){
1334 g.perm.Private = 1;
1335 xfer.syncPrivate = 1;
1336 }
1337
1338
--- src/xfer.c
+++ src/xfer.c
@@ -18,10 +18,12 @@
18 ** This file contains code to implement the file transfer protocol.
19 */
20 #include "config.h"
21 #include "xfer.h"
22
23 #include <time.h>
24
25 /*
26 ** This structure holds information about the current state of either
27 ** a client or a server that is participating in xfer.
28 */
29 typedef struct Xfer Xfer;
@@ -40,10 +42,11 @@
42 int nDeltaRcvd; /* Number of deltas received */
43 int nDanglingFile; /* Number of dangling deltas received */
44 int mxSend; /* Stop sending "file" with pOut reaches this size */
45 u8 syncPrivate; /* True to enable syncing private content */
46 u8 nextIsPrivate; /* If true, next "file" received is a private */
47 time_t maxTime; /* Time when this transfer should be finished */
48 };
49
50
51 /*
52 ** The input blob contains a UUID. Convert it into a record ID.
@@ -393,11 +396,12 @@
396 }
397 if( uuid_is_shunned(blob_str(pUuid)) ){
398 blob_reset(&uuid);
399 return;
400 }
401 if( (pXfer->maxTime != -1 && time(NULL) >= pXfer->maxTime) ||
402 pXfer->mxSend<=blob_size(pXfer->pOut) ){
403 const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n";
404 blob_appendf(pXfer->pOut, zFormat, pUuid);
405 pXfer->nIGotSent++;
406 blob_reset(&uuid);
407 return;
@@ -867,10 +871,13 @@
871 }
872 blob_zero(&xfer.err);
873 xfer.pIn = &g.cgiIn;
874 xfer.pOut = cgi_output_blob();
875 xfer.mxSend = db_get_int("max-download", 5000000);
876 xfer.maxTime = db_get_int("max-download-time", 30);
877 if( xfer.maxTime<1 ) xfer.maxTime = 1;
878 xfer.maxTime += time(NULL);
879 g.xferPanic = 1;
880
881 db_begin_transaction();
882 db_multi_exec(
883 "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
@@ -1034,11 +1041,12 @@
1041 if( iVers>=3 ){
1042 cgi_set_content_type("application/x-fossil-uncompressed");
1043 }
1044 blob_is_int(&xfer.aToken[2], &seqno);
1045 max = db_int(0, "SELECT max(rid) FROM blob");
1046 while( xfer.mxSend>blob_size(xfer.pOut) && seqno<=max){
1047 if( time(NULL) >= xfer.maxTime ) break;
1048 if( iVers>=3 ){
1049 send_compressed_file(&xfer, seqno);
1050 }else{
1051 send_file(&xfer, seqno, 0, 1);
1052 }
@@ -1328,10 +1336,11 @@
1336 socket_global_init();
1337 memset(&xfer, 0, sizeof(xfer));
1338 xfer.pIn = &recv;
1339 xfer.pOut = &send;
1340 xfer.mxSend = db_get_int("max-upload", 250000);
1341 xfer.maxTime = -1;
1342 if( syncFlags & SYNC_PRIVATE ){
1343 g.perm.Private = 1;
1344 xfer.syncPrivate = 1;
1345 }
1346
1347
+11 -2
--- src/xfer.c
+++ src/xfer.c
@@ -18,10 +18,12 @@
1818
** This file contains code to implement the file transfer protocol.
1919
*/
2020
#include "config.h"
2121
#include "xfer.h"
2222
23
+#include <time.h>
24
+
2325
/*
2426
** This structure holds information about the current state of either
2527
** a client or a server that is participating in xfer.
2628
*/
2729
typedef struct Xfer Xfer;
@@ -40,10 +42,11 @@
4042
int nDeltaRcvd; /* Number of deltas received */
4143
int nDanglingFile; /* Number of dangling deltas received */
4244
int mxSend; /* Stop sending "file" with pOut reaches this size */
4345
u8 syncPrivate; /* True to enable syncing private content */
4446
u8 nextIsPrivate; /* If true, next "file" received is a private */
47
+ time_t maxTime; /* Time when this transfer should be finished */
4548
};
4649
4750
4851
/*
4952
** The input blob contains a UUID. Convert it into a record ID.
@@ -393,11 +396,12 @@
393396
}
394397
if( uuid_is_shunned(blob_str(pUuid)) ){
395398
blob_reset(&uuid);
396399
return;
397400
}
398
- if( pXfer->mxSend<=blob_size(pXfer->pOut) ){
401
+ if( (pXfer->maxTime != -1 && time(NULL) >= pXfer->maxTime) ||
402
+ pXfer->mxSend<=blob_size(pXfer->pOut) ){
399403
const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n";
400404
blob_appendf(pXfer->pOut, zFormat, pUuid);
401405
pXfer->nIGotSent++;
402406
blob_reset(&uuid);
403407
return;
@@ -867,10 +871,13 @@
867871
}
868872
blob_zero(&xfer.err);
869873
xfer.pIn = &g.cgiIn;
870874
xfer.pOut = cgi_output_blob();
871875
xfer.mxSend = db_get_int("max-download", 5000000);
876
+ xfer.maxTime = db_get_int("max-download-time", 30);
877
+ if( xfer.maxTime<1 ) xfer.maxTime = 1;
878
+ xfer.maxTime += time(NULL);
872879
g.xferPanic = 1;
873880
874881
db_begin_transaction();
875882
db_multi_exec(
876883
"CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
@@ -1034,11 +1041,12 @@
10341041
if( iVers>=3 ){
10351042
cgi_set_content_type("application/x-fossil-uncompressed");
10361043
}
10371044
blob_is_int(&xfer.aToken[2], &seqno);
10381045
max = db_int(0, "SELECT max(rid) FROM blob");
1039
- while( xfer.mxSend>blob_size(xfer.pOut) && seqno<=max ){
1046
+ while( xfer.mxSend>blob_size(xfer.pOut) && seqno<=max){
1047
+ if( time(NULL) >= xfer.maxTime ) break;
10401048
if( iVers>=3 ){
10411049
send_compressed_file(&xfer, seqno);
10421050
}else{
10431051
send_file(&xfer, seqno, 0, 1);
10441052
}
@@ -1328,10 +1336,11 @@
13281336
socket_global_init();
13291337
memset(&xfer, 0, sizeof(xfer));
13301338
xfer.pIn = &recv;
13311339
xfer.pOut = &send;
13321340
xfer.mxSend = db_get_int("max-upload", 250000);
1341
+ xfer.maxTime = -1;
13331342
if( syncFlags & SYNC_PRIVATE ){
13341343
g.perm.Private = 1;
13351344
xfer.syncPrivate = 1;
13361345
}
13371346
13381347
--- src/xfer.c
+++ src/xfer.c
@@ -18,10 +18,12 @@
18 ** This file contains code to implement the file transfer protocol.
19 */
20 #include "config.h"
21 #include "xfer.h"
22
 
 
23 /*
24 ** This structure holds information about the current state of either
25 ** a client or a server that is participating in xfer.
26 */
27 typedef struct Xfer Xfer;
@@ -40,10 +42,11 @@
40 int nDeltaRcvd; /* Number of deltas received */
41 int nDanglingFile; /* Number of dangling deltas received */
42 int mxSend; /* Stop sending "file" with pOut reaches this size */
43 u8 syncPrivate; /* True to enable syncing private content */
44 u8 nextIsPrivate; /* If true, next "file" received is a private */
 
45 };
46
47
48 /*
49 ** The input blob contains a UUID. Convert it into a record ID.
@@ -393,11 +396,12 @@
393 }
394 if( uuid_is_shunned(blob_str(pUuid)) ){
395 blob_reset(&uuid);
396 return;
397 }
398 if( pXfer->mxSend<=blob_size(pXfer->pOut) ){
 
399 const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n";
400 blob_appendf(pXfer->pOut, zFormat, pUuid);
401 pXfer->nIGotSent++;
402 blob_reset(&uuid);
403 return;
@@ -867,10 +871,13 @@
867 }
868 blob_zero(&xfer.err);
869 xfer.pIn = &g.cgiIn;
870 xfer.pOut = cgi_output_blob();
871 xfer.mxSend = db_get_int("max-download", 5000000);
 
 
 
872 g.xferPanic = 1;
873
874 db_begin_transaction();
875 db_multi_exec(
876 "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
@@ -1034,11 +1041,12 @@
1034 if( iVers>=3 ){
1035 cgi_set_content_type("application/x-fossil-uncompressed");
1036 }
1037 blob_is_int(&xfer.aToken[2], &seqno);
1038 max = db_int(0, "SELECT max(rid) FROM blob");
1039 while( xfer.mxSend>blob_size(xfer.pOut) && seqno<=max ){
 
1040 if( iVers>=3 ){
1041 send_compressed_file(&xfer, seqno);
1042 }else{
1043 send_file(&xfer, seqno, 0, 1);
1044 }
@@ -1328,10 +1336,11 @@
1328 socket_global_init();
1329 memset(&xfer, 0, sizeof(xfer));
1330 xfer.pIn = &recv;
1331 xfer.pOut = &send;
1332 xfer.mxSend = db_get_int("max-upload", 250000);
 
1333 if( syncFlags & SYNC_PRIVATE ){
1334 g.perm.Private = 1;
1335 xfer.syncPrivate = 1;
1336 }
1337
1338
--- src/xfer.c
+++ src/xfer.c
@@ -18,10 +18,12 @@
18 ** This file contains code to implement the file transfer protocol.
19 */
20 #include "config.h"
21 #include "xfer.h"
22
23 #include <time.h>
24
25 /*
26 ** This structure holds information about the current state of either
27 ** a client or a server that is participating in xfer.
28 */
29 typedef struct Xfer Xfer;
@@ -40,10 +42,11 @@
42 int nDeltaRcvd; /* Number of deltas received */
43 int nDanglingFile; /* Number of dangling deltas received */
44 int mxSend; /* Stop sending "file" with pOut reaches this size */
45 u8 syncPrivate; /* True to enable syncing private content */
46 u8 nextIsPrivate; /* If true, next "file" received is a private */
47 time_t maxTime; /* Time when this transfer should be finished */
48 };
49
50
51 /*
52 ** The input blob contains a UUID. Convert it into a record ID.
@@ -393,11 +396,12 @@
396 }
397 if( uuid_is_shunned(blob_str(pUuid)) ){
398 blob_reset(&uuid);
399 return;
400 }
401 if( (pXfer->maxTime != -1 && time(NULL) >= pXfer->maxTime) ||
402 pXfer->mxSend<=blob_size(pXfer->pOut) ){
403 const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n";
404 blob_appendf(pXfer->pOut, zFormat, pUuid);
405 pXfer->nIGotSent++;
406 blob_reset(&uuid);
407 return;
@@ -867,10 +871,13 @@
871 }
872 blob_zero(&xfer.err);
873 xfer.pIn = &g.cgiIn;
874 xfer.pOut = cgi_output_blob();
875 xfer.mxSend = db_get_int("max-download", 5000000);
876 xfer.maxTime = db_get_int("max-download-time", 30);
877 if( xfer.maxTime<1 ) xfer.maxTime = 1;
878 xfer.maxTime += time(NULL);
879 g.xferPanic = 1;
880
881 db_begin_transaction();
882 db_multi_exec(
883 "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
@@ -1034,11 +1041,12 @@
1041 if( iVers>=3 ){
1042 cgi_set_content_type("application/x-fossil-uncompressed");
1043 }
1044 blob_is_int(&xfer.aToken[2], &seqno);
1045 max = db_int(0, "SELECT max(rid) FROM blob");
1046 while( xfer.mxSend>blob_size(xfer.pOut) && seqno<=max){
1047 if( time(NULL) >= xfer.maxTime ) break;
1048 if( iVers>=3 ){
1049 send_compressed_file(&xfer, seqno);
1050 }else{
1051 send_file(&xfer, seqno, 0, 1);
1052 }
@@ -1328,10 +1336,11 @@
1336 socket_global_init();
1337 memset(&xfer, 0, sizeof(xfer));
1338 xfer.pIn = &recv;
1339 xfer.pOut = &send;
1340 xfer.mxSend = db_get_int("max-upload", 250000);
1341 xfer.maxTime = -1;
1342 if( syncFlags & SYNC_PRIVATE ){
1343 g.perm.Private = 1;
1344 xfer.syncPrivate = 1;
1345 }
1346
1347

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button