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.

drh 2024-04-17 12:18 content-length-errors
Commit dfefd069b6026effb244718496a6d2d4b8dd820ad1b5ad025886e52e5e093516
2 files changed +2 +32 -8
--- src/clone.c
+++ src/clone.c
@@ -136,10 +136,11 @@
136136
** --ssl-identity FILENAME Use the SSL identity if requested by the server
137137
** --transport-command CMD Use CMD to move messages to the server and back
138138
** -u|--unversioned Also sync unversioned content
139139
** -v|--verbose Show more statistics in output
140140
** --workdir DIR Also open a check-out in DIR
141
+** --xverbose Extra debugging output
141142
**
142143
** See also: [[init]], [[open]]
143144
*/
144145
void clone_cmd(void){
145146
char *zPassword;
@@ -161,10 +162,11 @@
161162
if( find_option("save-http-password",0,0)!=0 ){
162163
urlFlags &= ~URL_PROMPT_PW;
163164
urlFlags |= URL_REMEMBER_PW;
164165
}
165166
if( find_option("verbose","v",0)!=0) syncFlags |= SYNC_VERBOSE;
167
+ if( find_option("xverbose",0,0)!=0) syncFlags |= SYNC_XVERBOSE;
166168
if( find_option("unversioned","u",0)!=0 ){
167169
syncFlags |= SYNC_UNVERSIONED;
168170
if( syncFlags & SYNC_VERBOSE ){
169171
syncFlags |= SYNC_UV_TRACE;
170172
}
171173
--- 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 @@
436436
Blob login; /* The login card */
437437
Blob payload; /* The complete payload including login card */
438438
Blob hdr; /* The HTTP request header */
439439
int closeConnection; /* True to close the connection when done */
440440
int iLength; /* Expected length of the reply payload */
441
- int iRecvLen; /* Received length of the reply payload */
442441
int rc = 0; /* Result code */
443442
int iHttpVersion; /* Which version of HTTP protocol server uses */
444443
char *zLine; /* A single line of the reply header */
445444
int i; /* Loop counter */
446445
int isError = 0; /* True if the reply is an error message */
@@ -525,10 +524,11 @@
525524
/*
526525
** Read and interpret the server reply
527526
*/
528527
closeConnection = 1;
529528
iLength = -1;
529
+ iHttpVersion = -1;
530530
while( (zLine = transport_receive_line(&g.url))!=0 && zLine[0]!=0 ){
531531
if( mHttpFlags & HTTP_VERBOSE ){
532532
fossil_print("Read: [%s]\n", zLine);
533533
}
534534
if( fossil_strnicmp(zLine, "http/1.", 7)==0 ){
@@ -636,11 +636,11 @@
636636
isError = 1;
637637
}
638638
}
639639
}
640640
}
641
- if( iLength<0 ){
641
+ if( iHttpVersion<0 ){
642642
/* We got nothing back from the server. If using the ssh: protocol,
643643
** this might mean we need to add or remove the PATH=... argument
644644
** to the SSH command being sent. If that is the case, retry the
645645
** request after adding or removing the PATH= argument.
646646
*/
@@ -682,17 +682,41 @@
682682
683683
/*
684684
** Extract the reply payload that follows the header
685685
*/
686686
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
+ }
692717
}
693
- blob_resize(pReply, iLength);
694718
if( isError ){
695719
char *z;
696720
int i, j;
697721
z = blob_str(pReply);
698722
for(i=j=0; z[i]; i++, j++){
699723
--- 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

Keyboard Shortcuts

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