| | @@ -18,10 +18,12 @@ |
| 18 | 18 | ** This file contains code to implement the file transfer protocol. |
| 19 | 19 | */ |
| 20 | 20 | #include "config.h" |
| 21 | 21 | #include "xfer.h" |
| 22 | 22 | |
| 23 | +#include <time.h> |
| 24 | + |
| 23 | 25 | /* |
| 24 | 26 | ** This structure holds information about the current state of either |
| 25 | 27 | ** a client or a server that is participating in xfer. |
| 26 | 28 | */ |
| 27 | 29 | typedef struct Xfer Xfer; |
| | @@ -40,10 +42,11 @@ |
| 40 | 42 | int nDeltaRcvd; /* Number of deltas received */ |
| 41 | 43 | int nDanglingFile; /* Number of dangling deltas received */ |
| 42 | 44 | int mxSend; /* Stop sending "file" with pOut reaches this size */ |
| 43 | 45 | u8 syncPrivate; /* True to enable syncing private content */ |
| 44 | 46 | u8 nextIsPrivate; /* If true, next "file" received is a private */ |
| 47 | + time_t maxTime; /* Time when this transfer should be finished */ |
| 45 | 48 | }; |
| 46 | 49 | |
| 47 | 50 | |
| 48 | 51 | /* |
| 49 | 52 | ** The input blob contains a UUID. Convert it into a record ID. |
| | @@ -393,11 +396,12 @@ |
| 393 | 396 | } |
| 394 | 397 | if( uuid_is_shunned(blob_str(pUuid)) ){ |
| 395 | 398 | blob_reset(&uuid); |
| 396 | 399 | return; |
| 397 | 400 | } |
| 398 | | - if( pXfer->mxSend<=blob_size(pXfer->pOut) ){ |
| 401 | + if( (pXfer->maxTime != -1 && time(NULL) >= pXfer->maxTime) || |
| 402 | + pXfer->mxSend<=blob_size(pXfer->pOut) ){ |
| 399 | 403 | const char *zFormat = isPriv ? "igot %b 1\n" : "igot %b\n"; |
| 400 | 404 | blob_appendf(pXfer->pOut, zFormat, pUuid); |
| 401 | 405 | pXfer->nIGotSent++; |
| 402 | 406 | blob_reset(&uuid); |
| 403 | 407 | return; |
| | @@ -867,10 +871,13 @@ |
| 867 | 871 | } |
| 868 | 872 | blob_zero(&xfer.err); |
| 869 | 873 | xfer.pIn = &g.cgiIn; |
| 870 | 874 | xfer.pOut = cgi_output_blob(); |
| 871 | 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); |
| 872 | 879 | g.xferPanic = 1; |
| 873 | 880 | |
| 874 | 881 | db_begin_transaction(); |
| 875 | 882 | db_multi_exec( |
| 876 | 883 | "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);" |
| | @@ -1034,11 +1041,12 @@ |
| 1034 | 1041 | if( iVers>=3 ){ |
| 1035 | 1042 | cgi_set_content_type("application/x-fossil-uncompressed"); |
| 1036 | 1043 | } |
| 1037 | 1044 | blob_is_int(&xfer.aToken[2], &seqno); |
| 1038 | 1045 | 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; |
| 1040 | 1048 | if( iVers>=3 ){ |
| 1041 | 1049 | send_compressed_file(&xfer, seqno); |
| 1042 | 1050 | }else{ |
| 1043 | 1051 | send_file(&xfer, seqno, 0, 1); |
| 1044 | 1052 | } |
| | @@ -1328,10 +1336,11 @@ |
| 1328 | 1336 | socket_global_init(); |
| 1329 | 1337 | memset(&xfer, 0, sizeof(xfer)); |
| 1330 | 1338 | xfer.pIn = &recv; |
| 1331 | 1339 | xfer.pOut = &send; |
| 1332 | 1340 | xfer.mxSend = db_get_int("max-upload", 250000); |
| 1341 | + xfer.maxTime = -1; |
| 1333 | 1342 | if( syncFlags & SYNC_PRIVATE ){ |
| 1334 | 1343 | g.perm.Private = 1; |
| 1335 | 1344 | xfer.syncPrivate = 1; |
| 1336 | 1345 | } |
| 1337 | 1346 | |
| 1338 | 1347 | |