Fossil SCM
The sync, clone, push, and pull commands process 302 redirects.
Commit
84439e9dc7077dcd1499773444c2ae96641daed0
Parent
a5a1ff1b4b5a1ae…
1 file changed
+20
-4
+20
-4
| --- src/http.c | ||
| +++ src/http.c | ||
| @@ -193,22 +193,23 @@ | ||
| 193 | 193 | closeConnection = 1; |
| 194 | 194 | iLength = -1; |
| 195 | 195 | while( (zLine = transport_receive_line())!=0 && zLine[0]!=0 ){ |
| 196 | 196 | if( strncasecmp(zLine, "http/1.", 7)==0 ){ |
| 197 | 197 | if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err; |
| 198 | - if( rc!=200 ){ | |
| 198 | + if( rc!=200 && rc!=302 ){ | |
| 199 | 199 | int ii; |
| 200 | 200 | for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){} |
| 201 | - printf("ERROR. server says: %s\n", &zLine[ii]); | |
| 201 | + while( zLine[ii]==' ' ) ii++; | |
| 202 | + fossil_fatal("server says: %s\n", &zLine[ii]); | |
| 202 | 203 | goto write_err; |
| 203 | 204 | } |
| 204 | 205 | if( iHttpVersion==0 ){ |
| 205 | 206 | closeConnection = 1; |
| 206 | 207 | }else{ |
| 207 | 208 | closeConnection = 0; |
| 208 | 209 | } |
| 209 | - } else if( strncasecmp(zLine, "content-length:", 15)==0 ){ | |
| 210 | + }else if( strncasecmp(zLine, "content-length:", 15)==0 ){ | |
| 210 | 211 | for(i=15; isspace(zLine[i]); i++){} |
| 211 | 212 | iLength = atoi(&zLine[i]); |
| 212 | 213 | }else if( strncasecmp(zLine, "connection:", 11)==0 ){ |
| 213 | 214 | char c; |
| 214 | 215 | for(i=11; isspace(zLine[i]); i++){} |
| @@ -216,18 +217,33 @@ | ||
| 216 | 217 | if( c=='c' || c=='C' ){ |
| 217 | 218 | closeConnection = 1; |
| 218 | 219 | }else if( c=='k' || c=='K' ){ |
| 219 | 220 | closeConnection = 0; |
| 220 | 221 | } |
| 222 | + }else if( rc==302 && strncasecmp(zLine, "location:", 9)==0 ){ | |
| 223 | + int i, j; | |
| 224 | + for(i=9; zLine[i] && zLine[i]==' '; i++){} | |
| 225 | + if( zLine[i]==0 ) fossil_fatal("malformed redirect: %s", zLine); | |
| 226 | + j = strlen(zLine) - 1; | |
| 227 | + if( j>4 && strcmp(&zLine[j-4],"/xfer")==0 ) zLine[j-4] = 0; | |
| 228 | + printf("redirect to %s\n", &zLine[i]); | |
| 229 | + url_parse(&zLine[i]); | |
| 230 | + transport_close(); | |
| 231 | + http_exchange(pSend, pReply, useLogin); | |
| 232 | + return; | |
| 221 | 233 | } |
| 222 | 234 | } |
| 235 | + if( rc!=200 ){ | |
| 236 | + fossil_fatal("\"location:\" missing from 302 redirect reply"); | |
| 237 | + goto write_err; | |
| 238 | + } | |
| 223 | 239 | |
| 224 | 240 | /* |
| 225 | 241 | ** Extract the reply payload that follows the header |
| 226 | 242 | */ |
| 227 | 243 | if( iLength<0 ){ |
| 228 | - printf("ERROR. Server did not reply\n"); | |
| 244 | + fossil_fatal("server did not reply"); | |
| 229 | 245 | goto write_err; |
| 230 | 246 | } |
| 231 | 247 | blob_zero(pReply); |
| 232 | 248 | blob_resize(pReply, iLength); |
| 233 | 249 | iLength = transport_receive(blob_buffer(pReply), iLength); |
| 234 | 250 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -193,22 +193,23 @@ | |
| 193 | closeConnection = 1; |
| 194 | iLength = -1; |
| 195 | while( (zLine = transport_receive_line())!=0 && zLine[0]!=0 ){ |
| 196 | if( strncasecmp(zLine, "http/1.", 7)==0 ){ |
| 197 | if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err; |
| 198 | if( rc!=200 ){ |
| 199 | int ii; |
| 200 | for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){} |
| 201 | printf("ERROR. server says: %s\n", &zLine[ii]); |
| 202 | goto write_err; |
| 203 | } |
| 204 | if( iHttpVersion==0 ){ |
| 205 | closeConnection = 1; |
| 206 | }else{ |
| 207 | closeConnection = 0; |
| 208 | } |
| 209 | } else if( strncasecmp(zLine, "content-length:", 15)==0 ){ |
| 210 | for(i=15; isspace(zLine[i]); i++){} |
| 211 | iLength = atoi(&zLine[i]); |
| 212 | }else if( strncasecmp(zLine, "connection:", 11)==0 ){ |
| 213 | char c; |
| 214 | for(i=11; isspace(zLine[i]); i++){} |
| @@ -216,18 +217,33 @@ | |
| 216 | if( c=='c' || c=='C' ){ |
| 217 | closeConnection = 1; |
| 218 | }else if( c=='k' || c=='K' ){ |
| 219 | closeConnection = 0; |
| 220 | } |
| 221 | } |
| 222 | } |
| 223 | |
| 224 | /* |
| 225 | ** Extract the reply payload that follows the header |
| 226 | */ |
| 227 | if( iLength<0 ){ |
| 228 | printf("ERROR. Server did not reply\n"); |
| 229 | goto write_err; |
| 230 | } |
| 231 | blob_zero(pReply); |
| 232 | blob_resize(pReply, iLength); |
| 233 | iLength = transport_receive(blob_buffer(pReply), iLength); |
| 234 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -193,22 +193,23 @@ | |
| 193 | closeConnection = 1; |
| 194 | iLength = -1; |
| 195 | while( (zLine = transport_receive_line())!=0 && zLine[0]!=0 ){ |
| 196 | if( strncasecmp(zLine, "http/1.", 7)==0 ){ |
| 197 | if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err; |
| 198 | if( rc!=200 && rc!=302 ){ |
| 199 | int ii; |
| 200 | for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){} |
| 201 | while( zLine[ii]==' ' ) ii++; |
| 202 | fossil_fatal("server says: %s\n", &zLine[ii]); |
| 203 | goto write_err; |
| 204 | } |
| 205 | if( iHttpVersion==0 ){ |
| 206 | closeConnection = 1; |
| 207 | }else{ |
| 208 | closeConnection = 0; |
| 209 | } |
| 210 | }else if( strncasecmp(zLine, "content-length:", 15)==0 ){ |
| 211 | for(i=15; isspace(zLine[i]); i++){} |
| 212 | iLength = atoi(&zLine[i]); |
| 213 | }else if( strncasecmp(zLine, "connection:", 11)==0 ){ |
| 214 | char c; |
| 215 | for(i=11; isspace(zLine[i]); i++){} |
| @@ -216,18 +217,33 @@ | |
| 217 | if( c=='c' || c=='C' ){ |
| 218 | closeConnection = 1; |
| 219 | }else if( c=='k' || c=='K' ){ |
| 220 | closeConnection = 0; |
| 221 | } |
| 222 | }else if( rc==302 && strncasecmp(zLine, "location:", 9)==0 ){ |
| 223 | int i, j; |
| 224 | for(i=9; zLine[i] && zLine[i]==' '; i++){} |
| 225 | if( zLine[i]==0 ) fossil_fatal("malformed redirect: %s", zLine); |
| 226 | j = strlen(zLine) - 1; |
| 227 | if( j>4 && strcmp(&zLine[j-4],"/xfer")==0 ) zLine[j-4] = 0; |
| 228 | printf("redirect to %s\n", &zLine[i]); |
| 229 | url_parse(&zLine[i]); |
| 230 | transport_close(); |
| 231 | http_exchange(pSend, pReply, useLogin); |
| 232 | return; |
| 233 | } |
| 234 | } |
| 235 | if( rc!=200 ){ |
| 236 | fossil_fatal("\"location:\" missing from 302 redirect reply"); |
| 237 | goto write_err; |
| 238 | } |
| 239 | |
| 240 | /* |
| 241 | ** Extract the reply payload that follows the header |
| 242 | */ |
| 243 | if( iLength<0 ){ |
| 244 | fossil_fatal("server did not reply"); |
| 245 | goto write_err; |
| 246 | } |
| 247 | blob_zero(pReply); |
| 248 | blob_resize(pReply, iLength); |
| 249 | iLength = transport_receive(blob_buffer(pReply), iLength); |
| 250 |