Fossil SCM
Arrange for the HTTP reply parser to be able to deal with a missing Content-Length header. Add the --xverbose option to the "fossil clone" command.
Commit
dfefd069b6026effb244718496a6d2d4b8dd820ad1b5ad025886e52e5e093516
Parent
131ba0fa1bf1e20…
2 files changed
+2
+32
-8
+2
| --- src/clone.c | ||
| +++ src/clone.c | ||
| @@ -136,10 +136,11 @@ | ||
| 136 | 136 | ** --ssl-identity FILENAME Use the SSL identity if requested by the server |
| 137 | 137 | ** --transport-command CMD Use CMD to move messages to the server and back |
| 138 | 138 | ** -u|--unversioned Also sync unversioned content |
| 139 | 139 | ** -v|--verbose Show more statistics in output |
| 140 | 140 | ** --workdir DIR Also open a check-out in DIR |
| 141 | +** --xverbose Extra debugging output | |
| 141 | 142 | ** |
| 142 | 143 | ** See also: [[init]], [[open]] |
| 143 | 144 | */ |
| 144 | 145 | void clone_cmd(void){ |
| 145 | 146 | char *zPassword; |
| @@ -161,10 +162,11 @@ | ||
| 161 | 162 | if( find_option("save-http-password",0,0)!=0 ){ |
| 162 | 163 | urlFlags &= ~URL_PROMPT_PW; |
| 163 | 164 | urlFlags |= URL_REMEMBER_PW; |
| 164 | 165 | } |
| 165 | 166 | if( find_option("verbose","v",0)!=0) syncFlags |= SYNC_VERBOSE; |
| 167 | + if( find_option("xverbose",0,0)!=0) syncFlags |= SYNC_XVERBOSE; | |
| 166 | 168 | if( find_option("unversioned","u",0)!=0 ){ |
| 167 | 169 | syncFlags |= SYNC_UNVERSIONED; |
| 168 | 170 | if( syncFlags & SYNC_VERBOSE ){ |
| 169 | 171 | syncFlags |= SYNC_UV_TRACE; |
| 170 | 172 | } |
| 171 | 173 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -136,10 +136,11 @@ | |
| 136 | ** --ssl-identity FILENAME Use the SSL identity if requested by the server |
| 137 | ** --transport-command CMD Use CMD to move messages to the server and back |
| 138 | ** -u|--unversioned Also sync unversioned content |
| 139 | ** -v|--verbose Show more statistics in output |
| 140 | ** --workdir DIR Also open a check-out in DIR |
| 141 | ** |
| 142 | ** See also: [[init]], [[open]] |
| 143 | */ |
| 144 | void clone_cmd(void){ |
| 145 | char *zPassword; |
| @@ -161,10 +162,11 @@ | |
| 161 | if( find_option("save-http-password",0,0)!=0 ){ |
| 162 | urlFlags &= ~URL_PROMPT_PW; |
| 163 | urlFlags |= URL_REMEMBER_PW; |
| 164 | } |
| 165 | if( find_option("verbose","v",0)!=0) syncFlags |= SYNC_VERBOSE; |
| 166 | if( find_option("unversioned","u",0)!=0 ){ |
| 167 | syncFlags |= SYNC_UNVERSIONED; |
| 168 | if( syncFlags & SYNC_VERBOSE ){ |
| 169 | syncFlags |= SYNC_UV_TRACE; |
| 170 | } |
| 171 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -136,10 +136,11 @@ | |
| 136 | ** --ssl-identity FILENAME Use the SSL identity if requested by the server |
| 137 | ** --transport-command CMD Use CMD to move messages to the server and back |
| 138 | ** -u|--unversioned Also sync unversioned content |
| 139 | ** -v|--verbose Show more statistics in output |
| 140 | ** --workdir DIR Also open a check-out in DIR |
| 141 | ** --xverbose Extra debugging output |
| 142 | ** |
| 143 | ** See also: [[init]], [[open]] |
| 144 | */ |
| 145 | void clone_cmd(void){ |
| 146 | char *zPassword; |
| @@ -161,10 +162,11 @@ | |
| 162 | if( find_option("save-http-password",0,0)!=0 ){ |
| 163 | urlFlags &= ~URL_PROMPT_PW; |
| 164 | urlFlags |= URL_REMEMBER_PW; |
| 165 | } |
| 166 | if( find_option("verbose","v",0)!=0) syncFlags |= SYNC_VERBOSE; |
| 167 | if( find_option("xverbose",0,0)!=0) syncFlags |= SYNC_XVERBOSE; |
| 168 | if( find_option("unversioned","u",0)!=0 ){ |
| 169 | syncFlags |= SYNC_UNVERSIONED; |
| 170 | if( syncFlags & SYNC_VERBOSE ){ |
| 171 | syncFlags |= SYNC_UV_TRACE; |
| 172 | } |
| 173 |
+32
-8
| --- src/http.c | ||
| +++ src/http.c | ||
| @@ -436,11 +436,10 @@ | ||
| 436 | 436 | Blob login; /* The login card */ |
| 437 | 437 | Blob payload; /* The complete payload including login card */ |
| 438 | 438 | Blob hdr; /* The HTTP request header */ |
| 439 | 439 | int closeConnection; /* True to close the connection when done */ |
| 440 | 440 | int iLength; /* Expected length of the reply payload */ |
| 441 | - int iRecvLen; /* Received length of the reply payload */ | |
| 442 | 441 | int rc = 0; /* Result code */ |
| 443 | 442 | int iHttpVersion; /* Which version of HTTP protocol server uses */ |
| 444 | 443 | char *zLine; /* A single line of the reply header */ |
| 445 | 444 | int i; /* Loop counter */ |
| 446 | 445 | int isError = 0; /* True if the reply is an error message */ |
| @@ -525,10 +524,11 @@ | ||
| 525 | 524 | /* |
| 526 | 525 | ** Read and interpret the server reply |
| 527 | 526 | */ |
| 528 | 527 | closeConnection = 1; |
| 529 | 528 | iLength = -1; |
| 529 | + iHttpVersion = -1; | |
| 530 | 530 | while( (zLine = transport_receive_line(&g.url))!=0 && zLine[0]!=0 ){ |
| 531 | 531 | if( mHttpFlags & HTTP_VERBOSE ){ |
| 532 | 532 | fossil_print("Read: [%s]\n", zLine); |
| 533 | 533 | } |
| 534 | 534 | if( fossil_strnicmp(zLine, "http/1.", 7)==0 ){ |
| @@ -636,11 +636,11 @@ | ||
| 636 | 636 | isError = 1; |
| 637 | 637 | } |
| 638 | 638 | } |
| 639 | 639 | } |
| 640 | 640 | } |
| 641 | - if( iLength<0 ){ | |
| 641 | + if( iHttpVersion<0 ){ | |
| 642 | 642 | /* We got nothing back from the server. If using the ssh: protocol, |
| 643 | 643 | ** this might mean we need to add or remove the PATH=... argument |
| 644 | 644 | ** to the SSH command being sent. If that is the case, retry the |
| 645 | 645 | ** request after adding or removing the PATH= argument. |
| 646 | 646 | */ |
| @@ -682,17 +682,41 @@ | ||
| 682 | 682 | |
| 683 | 683 | /* |
| 684 | 684 | ** Extract the reply payload that follows the header |
| 685 | 685 | */ |
| 686 | 686 | blob_zero(pReply); |
| 687 | - blob_resize(pReply, iLength); | |
| 688 | - iRecvLen = transport_receive(&g.url, blob_buffer(pReply), iLength); | |
| 689 | - if( iRecvLen != iLength ){ | |
| 690 | - fossil_warning("response truncated: got %d bytes of %d", iRecvLen, iLength); | |
| 691 | - goto write_err; | |
| 687 | + if( iLength==0 ){ | |
| 688 | + /* No content to read */ | |
| 689 | + }else if( iLength>0 ){ | |
| 690 | + /* Read content of a known length */ | |
| 691 | + int iRecvLen; /* Received length of the reply payload */ | |
| 692 | + blob_resize(pReply, iLength); | |
| 693 | + iRecvLen = transport_receive(&g.url, blob_buffer(pReply), iLength); | |
| 694 | + if( mHttpFlags & HTTP_VERBOSE ){ | |
| 695 | + fossil_print("Reply received: %d of %d bytes\n", iRecvLen, iLength); | |
| 696 | + } | |
| 697 | + if( iRecvLen != iLength ){ | |
| 698 | + fossil_warning("response truncated: got %d bytes of %d", | |
| 699 | + iRecvLen, iLength); | |
| 700 | + goto write_err; | |
| 701 | + } | |
| 702 | + }else{ | |
| 703 | + /* Read content until end-of-file */ | |
| 704 | + int iRecvLen; /* Received length of the reply payload */ | |
| 705 | + unsigned int nReq = 1000; | |
| 706 | + unsigned int nPrior = 0; | |
| 707 | + do{ | |
| 708 | + nReq *= 2; | |
| 709 | + blob_resize(pReply, nPrior+nReq); | |
| 710 | + iRecvLen = transport_receive(&g.url, &pReply->aData[nPrior], (int)nReq); | |
| 711 | + nPrior += iRecvLen; | |
| 712 | + pReply->nUsed = nPrior; | |
| 713 | + }while( iRecvLen==nReq && nReq<0x20000000 ); | |
| 714 | + if( mHttpFlags & HTTP_VERBOSE ){ | |
| 715 | + fossil_print("Reply received: %u bytes (w/o content-length)\n", nPrior); | |
| 716 | + } | |
| 692 | 717 | } |
| 693 | - blob_resize(pReply, iLength); | |
| 694 | 718 | if( isError ){ |
| 695 | 719 | char *z; |
| 696 | 720 | int i, j; |
| 697 | 721 | z = blob_str(pReply); |
| 698 | 722 | for(i=j=0; z[i]; i++, j++){ |
| 699 | 723 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -436,11 +436,10 @@ | |
| 436 | Blob login; /* The login card */ |
| 437 | Blob payload; /* The complete payload including login card */ |
| 438 | Blob hdr; /* The HTTP request header */ |
| 439 | int closeConnection; /* True to close the connection when done */ |
| 440 | int iLength; /* Expected length of the reply payload */ |
| 441 | int iRecvLen; /* Received length of the reply payload */ |
| 442 | int rc = 0; /* Result code */ |
| 443 | int iHttpVersion; /* Which version of HTTP protocol server uses */ |
| 444 | char *zLine; /* A single line of the reply header */ |
| 445 | int i; /* Loop counter */ |
| 446 | int isError = 0; /* True if the reply is an error message */ |
| @@ -525,10 +524,11 @@ | |
| 525 | /* |
| 526 | ** Read and interpret the server reply |
| 527 | */ |
| 528 | closeConnection = 1; |
| 529 | iLength = -1; |
| 530 | while( (zLine = transport_receive_line(&g.url))!=0 && zLine[0]!=0 ){ |
| 531 | if( mHttpFlags & HTTP_VERBOSE ){ |
| 532 | fossil_print("Read: [%s]\n", zLine); |
| 533 | } |
| 534 | if( fossil_strnicmp(zLine, "http/1.", 7)==0 ){ |
| @@ -636,11 +636,11 @@ | |
| 636 | isError = 1; |
| 637 | } |
| 638 | } |
| 639 | } |
| 640 | } |
| 641 | if( iLength<0 ){ |
| 642 | /* We got nothing back from the server. If using the ssh: protocol, |
| 643 | ** this might mean we need to add or remove the PATH=... argument |
| 644 | ** to the SSH command being sent. If that is the case, retry the |
| 645 | ** request after adding or removing the PATH= argument. |
| 646 | */ |
| @@ -682,17 +682,41 @@ | |
| 682 | |
| 683 | /* |
| 684 | ** Extract the reply payload that follows the header |
| 685 | */ |
| 686 | blob_zero(pReply); |
| 687 | blob_resize(pReply, iLength); |
| 688 | iRecvLen = transport_receive(&g.url, blob_buffer(pReply), iLength); |
| 689 | if( iRecvLen != iLength ){ |
| 690 | fossil_warning("response truncated: got %d bytes of %d", iRecvLen, iLength); |
| 691 | goto write_err; |
| 692 | } |
| 693 | blob_resize(pReply, iLength); |
| 694 | if( isError ){ |
| 695 | char *z; |
| 696 | int i, j; |
| 697 | z = blob_str(pReply); |
| 698 | for(i=j=0; z[i]; i++, j++){ |
| 699 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -436,11 +436,10 @@ | |
| 436 | Blob login; /* The login card */ |
| 437 | Blob payload; /* The complete payload including login card */ |
| 438 | Blob hdr; /* The HTTP request header */ |
| 439 | int closeConnection; /* True to close the connection when done */ |
| 440 | int iLength; /* Expected length of the reply payload */ |
| 441 | int rc = 0; /* Result code */ |
| 442 | int iHttpVersion; /* Which version of HTTP protocol server uses */ |
| 443 | char *zLine; /* A single line of the reply header */ |
| 444 | int i; /* Loop counter */ |
| 445 | int isError = 0; /* True if the reply is an error message */ |
| @@ -525,10 +524,11 @@ | |
| 524 | /* |
| 525 | ** Read and interpret the server reply |
| 526 | */ |
| 527 | closeConnection = 1; |
| 528 | iLength = -1; |
| 529 | iHttpVersion = -1; |
| 530 | while( (zLine = transport_receive_line(&g.url))!=0 && zLine[0]!=0 ){ |
| 531 | if( mHttpFlags & HTTP_VERBOSE ){ |
| 532 | fossil_print("Read: [%s]\n", zLine); |
| 533 | } |
| 534 | if( fossil_strnicmp(zLine, "http/1.", 7)==0 ){ |
| @@ -636,11 +636,11 @@ | |
| 636 | isError = 1; |
| 637 | } |
| 638 | } |
| 639 | } |
| 640 | } |
| 641 | if( iHttpVersion<0 ){ |
| 642 | /* We got nothing back from the server. If using the ssh: protocol, |
| 643 | ** this might mean we need to add or remove the PATH=... argument |
| 644 | ** to the SSH command being sent. If that is the case, retry the |
| 645 | ** request after adding or removing the PATH= argument. |
| 646 | */ |
| @@ -682,17 +682,41 @@ | |
| 682 | |
| 683 | /* |
| 684 | ** Extract the reply payload that follows the header |
| 685 | */ |
| 686 | blob_zero(pReply); |
| 687 | if( iLength==0 ){ |
| 688 | /* No content to read */ |
| 689 | }else if( iLength>0 ){ |
| 690 | /* Read content of a known length */ |
| 691 | int iRecvLen; /* Received length of the reply payload */ |
| 692 | blob_resize(pReply, iLength); |
| 693 | iRecvLen = transport_receive(&g.url, blob_buffer(pReply), iLength); |
| 694 | if( mHttpFlags & HTTP_VERBOSE ){ |
| 695 | fossil_print("Reply received: %d of %d bytes\n", iRecvLen, iLength); |
| 696 | } |
| 697 | if( iRecvLen != iLength ){ |
| 698 | fossil_warning("response truncated: got %d bytes of %d", |
| 699 | iRecvLen, iLength); |
| 700 | goto write_err; |
| 701 | } |
| 702 | }else{ |
| 703 | /* Read content until end-of-file */ |
| 704 | int iRecvLen; /* Received length of the reply payload */ |
| 705 | unsigned int nReq = 1000; |
| 706 | unsigned int nPrior = 0; |
| 707 | do{ |
| 708 | nReq *= 2; |
| 709 | blob_resize(pReply, nPrior+nReq); |
| 710 | iRecvLen = transport_receive(&g.url, &pReply->aData[nPrior], (int)nReq); |
| 711 | nPrior += iRecvLen; |
| 712 | pReply->nUsed = nPrior; |
| 713 | }while( iRecvLen==nReq && nReq<0x20000000 ); |
| 714 | if( mHttpFlags & HTTP_VERBOSE ){ |
| 715 | fossil_print("Reply received: %u bytes (w/o content-length)\n", nPrior); |
| 716 | } |
| 717 | } |
| 718 | if( isError ){ |
| 719 | char *z; |
| 720 | int i, j; |
| 721 | z = blob_str(pReply); |
| 722 | for(i=j=0; z[i]; i++, j++){ |
| 723 |