Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Add support for the Range: attribute in HTTP requests for the "fossil server" and "fossil http" commands. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
b6892ccdd6f8f62522c325decdf2fe0e |
| User & Date: | drh 2020-03-15 18:35:54.297 |
Context
|
2020-03-15
| ||
| 20:43 | Fix the /announce/test2 feature so that it works without asserting. ... (check-in: ea4ccfdc2d user: drh tags: trunk) | |
| 18:35 | Add support for the Range: attribute in HTTP requests for the "fossil server" and "fossil http" commands. ... (check-in: b6892ccdd6 user: drh tags: trunk) | |
| 15:43 | Introduce a new version of db_multi_exec() that does not do printf-style formatting. ... (check-in: 0ea56bb239 user: drh tags: trunk) | |
| 15:22 | Experimental support for "Range:" headers in HTTP requests. ... (Closed-Leaf check-in: 37c615ad29 user: drh tags: http-range) | |
Changes
Changes to src/cgi.c.
| ︙ | ︙ | |||
176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
/*
** Additional information used to form the HTTP reply
*/
static const char *zContentType = "text/html"; /* Content type of the reply */
static const char *zReplyStatus = "OK"; /* Reply status description */
static int iReplyStatus = 200; /* Reply status code */
static Blob extraHeader = BLOB_INITIALIZER; /* Extra header text */
/*
** Set the reply content type
*/
void cgi_set_content_type(const char *zType){
zContentType = mprintf("%s", zType);
}
| > > | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
/*
** Additional information used to form the HTTP reply
*/
static const char *zContentType = "text/html"; /* Content type of the reply */
static const char *zReplyStatus = "OK"; /* Reply status description */
static int iReplyStatus = 200; /* Reply status code */
static Blob extraHeader = BLOB_INITIALIZER; /* Extra header text */
static int rangeStart = 0; /* Start of Range: */
static int rangeEnd = 0; /* End of Range: plus 1 */
/*
** Set the reply content type
*/
void cgi_set_content_type(const char *zType){
zContentType = mprintf("%s", zType);
}
|
| ︙ | ︙ | |||
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 |
int total_size;
if( iReplyStatus<=0 ){
iReplyStatus = 200;
zReplyStatus = "OK";
}
if( g.fullHttpReply ){
fprintf(g.httpOut, "HTTP/1.0 %d %s\r\n", iReplyStatus, zReplyStatus);
fprintf(g.httpOut, "Date: %s\r\n", cgi_rfc822_datestamp(time(0)));
fprintf(g.httpOut, "Connection: close\r\n");
fprintf(g.httpOut, "X-UA-Compatible: IE=edge\r\n");
}else{
fprintf(g.httpOut, "Status: %d %s\r\n", iReplyStatus, zReplyStatus);
}
if( g.isConst ){
/* isConst means that the reply is guaranteed to be invariant, even
** after configuration changes and/or Fossil binary recompiles. */
fprintf(g.httpOut, "Cache-Control: max-age=31536000\r\n");
}else if( etag_tag()!=0 ){
| > > > > > > > | 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 |
int total_size;
if( iReplyStatus<=0 ){
iReplyStatus = 200;
zReplyStatus = "OK";
}
if( g.fullHttpReply ){
if( rangeEnd>0
&& iReplyStatus==200
&& fossil_strcmp(P("REQUEST_METHOD"),"GET")==0
){
iReplyStatus = 206;
}
fprintf(g.httpOut, "HTTP/1.0 %d %s\r\n", iReplyStatus, zReplyStatus);
fprintf(g.httpOut, "Date: %s\r\n", cgi_rfc822_datestamp(time(0)));
fprintf(g.httpOut, "Connection: close\r\n");
fprintf(g.httpOut, "X-UA-Compatible: IE=edge\r\n");
}else{
assert( rangeEnd==0 );
fprintf(g.httpOut, "Status: %d %s\r\n", iReplyStatus, zReplyStatus);
}
if( g.isConst ){
/* isConst means that the reply is guaranteed to be invariant, even
** after configuration changes and/or Fossil binary recompiles. */
fprintf(g.httpOut, "Cache-Control: max-age=31536000\r\n");
}else if( etag_tag()!=0 ){
|
| ︙ | ︙ | |||
323 324 325 326 327 328 329 |
*/
fprintf(g.httpOut, "Content-Type: %s; charset=utf-8\r\n", zContentType);
if( fossil_strcmp(zContentType,"application/x-fossil")==0 ){
cgi_combine_header_and_body();
blob_compress(&cgiContent[0], &cgiContent[0]);
}
| | | > > > > > | > > > > > > | > > | 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 |
*/
fprintf(g.httpOut, "Content-Type: %s; charset=utf-8\r\n", zContentType);
if( fossil_strcmp(zContentType,"application/x-fossil")==0 ){
cgi_combine_header_and_body();
blob_compress(&cgiContent[0], &cgiContent[0]);
}
if( iReplyStatus!=304 ) {
if( is_gzippable() && iReplyStatus!=206 ){
int i;
gzip_begin(0);
for( i=0; i<2; i++ ){
int size = blob_size(&cgiContent[i]);
if( size>0 ) gzip_step(blob_buffer(&cgiContent[i]), size);
blob_reset(&cgiContent[i]);
}
gzip_finish(&cgiContent[0]);
fprintf(g.httpOut, "Content-Encoding: gzip\r\n");
fprintf(g.httpOut, "Vary: Accept-Encoding\r\n");
}
total_size = blob_size(&cgiContent[0]) + blob_size(&cgiContent[1]);
if( iReplyStatus==206 ){
fprintf(g.httpOut, "Content-Range: bytes %d-%d/%d\r\n",
rangeStart, rangeEnd-1, total_size);
total_size = rangeEnd - rangeStart;
}
fprintf(g.httpOut, "Content-Length: %d\r\n", total_size);
}else{
total_size = 0;
}
fprintf(g.httpOut, "\r\n");
if( total_size>0 && iReplyStatus != 304
&& fossil_strcmp(P("REQUEST_METHOD"),"HEAD")!=0
){
int i, size;
for(i=0; i<2; i++){
size = blob_size(&cgiContent[i]);
if( size<=rangeStart ){
rangeStart -= size;
}else{
int n = size - rangeStart;
if( n>total_size ){
n = total_size;
}
fwrite(blob_buffer(&cgiContent[i])+rangeStart, 1, n, g.httpOut);
rangeStart = 0;
total_size -= n;
}
}
}
fflush(g.httpOut);
CGIDEBUG(("-------- END cgi ---------\n"));
/* After the webpage has been sent, do any useful background
|
| ︙ | ︙ | |||
1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 |
}else if( fossil_strcmp(zFieldName,"authorization:")==0 ){
cgi_setenv("HTTP_AUTHORIZATION", zVal);
}else if( fossil_strcmp(zFieldName,"x-forwarded-for:")==0 ){
const char *zIpAddr = cgi_accept_forwarded_for(zVal);
if( zIpAddr!=0 ){
g.zIpAddr = mprintf("%s", zIpAddr);
cgi_replace_parameter("REMOTE_ADDR", g.zIpAddr);
}
}
}
cgi_init();
cgi_trace(0);
}
| > > > > > > > | 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 |
}else if( fossil_strcmp(zFieldName,"authorization:")==0 ){
cgi_setenv("HTTP_AUTHORIZATION", zVal);
}else if( fossil_strcmp(zFieldName,"x-forwarded-for:")==0 ){
const char *zIpAddr = cgi_accept_forwarded_for(zVal);
if( zIpAddr!=0 ){
g.zIpAddr = mprintf("%s", zIpAddr);
cgi_replace_parameter("REMOTE_ADDR", g.zIpAddr);
}
}else if( fossil_strcmp(zFieldName,"range:")==0 ){
int x1 = 0;
int x2 = 0;
if( sscanf(zVal,"bytes=%d-%d",&x1,&x2)==2 && x1>=0 && x1<=x2 ){
rangeStart = x1;
rangeEnd = x2+1;
}
}
}
cgi_init();
cgi_trace(0);
}
|
| ︙ | ︙ |