Fossil SCM

Fix the SSL-server code so that the "fossil ui --tls" command (and similar) now work on Windows.

drh 2021-12-29 02:59 trunk
Commit 7a3bf55f5489f5348830c5f116d872c26207121fbfd916653463f189bfa754ab
3 files changed +15 -17 +2 -5 +56 -18
+15 -17
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -739,41 +739,37 @@
739739
}
740740
if( !SSL_CTX_check_private_key(sslCtx) ){
741741
fossil_fatal("PRIVATE KEY \"%s\" does not match CERT \"%s\"",
742742
zKeyFile, zCertFile);
743743
}
744
+ SSL_CTX_set_mode(sslCtx, SSL_MODE_AUTO_RETRY);
744745
sslIsInit = 2;
745746
}else{
746747
assert( sslIsInit==2 );
747748
}
748749
}
749750
750751
typedef struct SslServerConn {
751752
SSL *ssl; /* The SSL codec */
752753
int atEof; /* True when EOF reached. */
753
- int fd0; /* Read channel, or socket */
754
- int fd1; /* Write channel */
754
+ int iSocket; /* The socket */
755755
} SslServerConn;
756756
757757
/*
758758
** Create a new server-side codec. The arguments are the file
759759
** descriptors from which teh codec reads and writes, respectively.
760760
**
761761
** If the writeFd is negative, then use then the readFd is a socket
762762
** over which we both read and write.
763763
*/
764
-void *ssl_new_server(int readFd, int writeFd){
764
+void *ssl_new_server(int iSocket){
765765
SslServerConn *pServer = fossil_malloc_zero(sizeof(*pServer));
766
+ BIO *b = BIO_new_socket(iSocket, 0);
766767
pServer->ssl = SSL_new(sslCtx);
767
- pServer->fd0 = readFd;
768
- pServer->fd1 = writeFd;
769
- if( writeFd<0 ){
770
- SSL_set_fd(pServer->ssl, readFd);
771
- }else{
772
- SSL_set_rfd(pServer->ssl, readFd);
773
- SSL_set_wfd(pServer->ssl, writeFd);
774
- }
768
+ pServer->atEof = 0;
769
+ pServer->iSocket = iSocket;
770
+ SSL_set_bio(pServer->ssl, b, b);
775771
SSL_accept(pServer->ssl);
776772
return (void*)pServer;
777773
}
778774
779775
/*
@@ -780,12 +776,10 @@
780776
** Close a server-side code previously returned from ssl_new_server().
781777
*/
782778
void ssl_close_server(void *pServerArg){
783779
SslServerConn *pServer = (SslServerConn*)pServerArg;
784780
SSL_free(pServer->ssl);
785
- close(pServer->fd0);
786
- if( pServer->fd1>=0 ) close(pServer->fd0);
787781
fossil_free(pServer);
788782
}
789783
790784
/*
791785
** Return TRUE if there are no more bytes available to be read from
@@ -804,12 +798,12 @@
804798
int n;
805799
SslServerConn *pServer = (SslServerConn*)pServerArg;
806800
if( pServer->atEof ) return 0;
807801
if( nBuf>0x7fffffff ){ fossil_fatal("SSL read too big"); }
808802
n = SSL_read(pServer->ssl, zBuf, (int)nBuf);
809
- if( n<nBuf ) pServer->atEof = 1;
810
- return n;
803
+ if( n==0 ) pServer->atEof = 1;
804
+ return n<=0 ? 0 : n;
811805
}
812806
813807
/*
814808
** Read a single line of text from the client.
815809
*/
@@ -836,14 +830,18 @@
836830
** be encrypted and sent back to the client.
837831
*/
838832
size_t ssl_write_server(void *pServerArg, char *zBuf, size_t nBuf){
839833
int n;
840834
SslServerConn *pServer = (SslServerConn*)pServerArg;
841
- if( pServer->atEof ) return 0;
835
+ if( nBuf<=0 ) return 0;
842836
if( nBuf>0x7fffffff ){ fossil_fatal("SSL write too big"); }
843837
n = SSL_write(pServer->ssl, zBuf, (int)nBuf);
844
- return n;
838
+ if( n<=0 ){
839
+ return -SSL_get_error(pServer->ssl, n);
840
+ }else{
841
+ return n;
842
+ }
845843
}
846844
847845
#endif /* FOSSIL_ENABLE_SSL */
848846
849847
/*
850848
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -739,41 +739,37 @@
739 }
740 if( !SSL_CTX_check_private_key(sslCtx) ){
741 fossil_fatal("PRIVATE KEY \"%s\" does not match CERT \"%s\"",
742 zKeyFile, zCertFile);
743 }
 
744 sslIsInit = 2;
745 }else{
746 assert( sslIsInit==2 );
747 }
748 }
749
750 typedef struct SslServerConn {
751 SSL *ssl; /* The SSL codec */
752 int atEof; /* True when EOF reached. */
753 int fd0; /* Read channel, or socket */
754 int fd1; /* Write channel */
755 } SslServerConn;
756
757 /*
758 ** Create a new server-side codec. The arguments are the file
759 ** descriptors from which teh codec reads and writes, respectively.
760 **
761 ** If the writeFd is negative, then use then the readFd is a socket
762 ** over which we both read and write.
763 */
764 void *ssl_new_server(int readFd, int writeFd){
765 SslServerConn *pServer = fossil_malloc_zero(sizeof(*pServer));
 
766 pServer->ssl = SSL_new(sslCtx);
767 pServer->fd0 = readFd;
768 pServer->fd1 = writeFd;
769 if( writeFd<0 ){
770 SSL_set_fd(pServer->ssl, readFd);
771 }else{
772 SSL_set_rfd(pServer->ssl, readFd);
773 SSL_set_wfd(pServer->ssl, writeFd);
774 }
775 SSL_accept(pServer->ssl);
776 return (void*)pServer;
777 }
778
779 /*
@@ -780,12 +776,10 @@
780 ** Close a server-side code previously returned from ssl_new_server().
781 */
782 void ssl_close_server(void *pServerArg){
783 SslServerConn *pServer = (SslServerConn*)pServerArg;
784 SSL_free(pServer->ssl);
785 close(pServer->fd0);
786 if( pServer->fd1>=0 ) close(pServer->fd0);
787 fossil_free(pServer);
788 }
789
790 /*
791 ** Return TRUE if there are no more bytes available to be read from
@@ -804,12 +798,12 @@
804 int n;
805 SslServerConn *pServer = (SslServerConn*)pServerArg;
806 if( pServer->atEof ) return 0;
807 if( nBuf>0x7fffffff ){ fossil_fatal("SSL read too big"); }
808 n = SSL_read(pServer->ssl, zBuf, (int)nBuf);
809 if( n<nBuf ) pServer->atEof = 1;
810 return n;
811 }
812
813 /*
814 ** Read a single line of text from the client.
815 */
@@ -836,14 +830,18 @@
836 ** be encrypted and sent back to the client.
837 */
838 size_t ssl_write_server(void *pServerArg, char *zBuf, size_t nBuf){
839 int n;
840 SslServerConn *pServer = (SslServerConn*)pServerArg;
841 if( pServer->atEof ) return 0;
842 if( nBuf>0x7fffffff ){ fossil_fatal("SSL write too big"); }
843 n = SSL_write(pServer->ssl, zBuf, (int)nBuf);
844 return n;
 
 
 
 
845 }
846
847 #endif /* FOSSIL_ENABLE_SSL */
848
849 /*
850
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -739,41 +739,37 @@
739 }
740 if( !SSL_CTX_check_private_key(sslCtx) ){
741 fossil_fatal("PRIVATE KEY \"%s\" does not match CERT \"%s\"",
742 zKeyFile, zCertFile);
743 }
744 SSL_CTX_set_mode(sslCtx, SSL_MODE_AUTO_RETRY);
745 sslIsInit = 2;
746 }else{
747 assert( sslIsInit==2 );
748 }
749 }
750
751 typedef struct SslServerConn {
752 SSL *ssl; /* The SSL codec */
753 int atEof; /* True when EOF reached. */
754 int iSocket; /* The socket */
 
755 } SslServerConn;
756
757 /*
758 ** Create a new server-side codec. The arguments are the file
759 ** descriptors from which teh codec reads and writes, respectively.
760 **
761 ** If the writeFd is negative, then use then the readFd is a socket
762 ** over which we both read and write.
763 */
764 void *ssl_new_server(int iSocket){
765 SslServerConn *pServer = fossil_malloc_zero(sizeof(*pServer));
766 BIO *b = BIO_new_socket(iSocket, 0);
767 pServer->ssl = SSL_new(sslCtx);
768 pServer->atEof = 0;
769 pServer->iSocket = iSocket;
770 SSL_set_bio(pServer->ssl, b, b);
 
 
 
 
 
771 SSL_accept(pServer->ssl);
772 return (void*)pServer;
773 }
774
775 /*
@@ -780,12 +776,10 @@
776 ** Close a server-side code previously returned from ssl_new_server().
777 */
778 void ssl_close_server(void *pServerArg){
779 SslServerConn *pServer = (SslServerConn*)pServerArg;
780 SSL_free(pServer->ssl);
 
 
781 fossil_free(pServer);
782 }
783
784 /*
785 ** Return TRUE if there are no more bytes available to be read from
@@ -804,12 +798,12 @@
798 int n;
799 SslServerConn *pServer = (SslServerConn*)pServerArg;
800 if( pServer->atEof ) return 0;
801 if( nBuf>0x7fffffff ){ fossil_fatal("SSL read too big"); }
802 n = SSL_read(pServer->ssl, zBuf, (int)nBuf);
803 if( n==0 ) pServer->atEof = 1;
804 return n<=0 ? 0 : n;
805 }
806
807 /*
808 ** Read a single line of text from the client.
809 */
@@ -836,14 +830,18 @@
830 ** be encrypted and sent back to the client.
831 */
832 size_t ssl_write_server(void *pServerArg, char *zBuf, size_t nBuf){
833 int n;
834 SslServerConn *pServer = (SslServerConn*)pServerArg;
835 if( nBuf<=0 ) return 0;
836 if( nBuf>0x7fffffff ){ fossil_fatal("SSL write too big"); }
837 n = SSL_write(pServer->ssl, zBuf, (int)nBuf);
838 if( n<=0 ){
839 return -SSL_get_error(pServer->ssl, n);
840 }else{
841 return n;
842 }
843 }
844
845 #endif /* FOSSIL_ENABLE_SSL */
846
847 /*
848
+2 -5
--- src/main.c
+++ src/main.c
@@ -2786,11 +2786,11 @@
27862786
}else if( g.fSshClient & CGI_SSH_CLIENT ){
27872787
ssh_request_loop(zIpAddr, glob_create(zFileGlob));
27882788
}else{
27892789
#if FOSSIL_ENABLE_SSL
27902790
if( g.httpUseSSL ){
2791
- g.httpSSLConn = ssl_new_server(0,-1);
2791
+ g.httpSSLConn = ssl_new_server(0);
27922792
}
27932793
#endif
27942794
cgi_handle_http_request(zIpAddr);
27952795
}
27962796
process_one_web_page(zNotFound, glob_create(zFileGlob), allowRepoList);
@@ -3286,11 +3286,11 @@
32863286
}
32873287
if( flags & HTTP_SERVER_SCGI ){
32883288
cgi_handle_scgi_request();
32893289
}else if( g.httpUseSSL ){
32903290
#if FOSSIL_ENABLE_SSL
3291
- g.httpSSLConn = ssl_new_server(0,-1);
3291
+ g.httpSSLConn = ssl_new_server(0);
32923292
#endif
32933293
cgi_handle_http_request(0);
32943294
}else{
32953295
cgi_handle_http_request(0);
32963296
}
@@ -3306,13 +3306,10 @@
33063306
}
33073307
#endif /* FOSSIL_ENABLE_SSL */
33083308
33093309
#else /* WIN32 */
33103310
/* Win32 implementation */
3311
- if( g.httpUseSSL ){
3312
- fossil_fatal("TLS-encrypted server is not (yet) supported on Windows");
3313
- }
33143311
if( allowRepoList ){
33153312
flags |= HTTP_SERVER_REPOLIST;
33163313
}
33173314
if( win32_http_service(iPort, zAltBase, zNotFound, zFileGlob, flags) ){
33183315
win32_http_server(iPort, mxPort, zBrowserCmd, zStopperFile,
33193316
--- src/main.c
+++ src/main.c
@@ -2786,11 +2786,11 @@
2786 }else if( g.fSshClient & CGI_SSH_CLIENT ){
2787 ssh_request_loop(zIpAddr, glob_create(zFileGlob));
2788 }else{
2789 #if FOSSIL_ENABLE_SSL
2790 if( g.httpUseSSL ){
2791 g.httpSSLConn = ssl_new_server(0,-1);
2792 }
2793 #endif
2794 cgi_handle_http_request(zIpAddr);
2795 }
2796 process_one_web_page(zNotFound, glob_create(zFileGlob), allowRepoList);
@@ -3286,11 +3286,11 @@
3286 }
3287 if( flags & HTTP_SERVER_SCGI ){
3288 cgi_handle_scgi_request();
3289 }else if( g.httpUseSSL ){
3290 #if FOSSIL_ENABLE_SSL
3291 g.httpSSLConn = ssl_new_server(0,-1);
3292 #endif
3293 cgi_handle_http_request(0);
3294 }else{
3295 cgi_handle_http_request(0);
3296 }
@@ -3306,13 +3306,10 @@
3306 }
3307 #endif /* FOSSIL_ENABLE_SSL */
3308
3309 #else /* WIN32 */
3310 /* Win32 implementation */
3311 if( g.httpUseSSL ){
3312 fossil_fatal("TLS-encrypted server is not (yet) supported on Windows");
3313 }
3314 if( allowRepoList ){
3315 flags |= HTTP_SERVER_REPOLIST;
3316 }
3317 if( win32_http_service(iPort, zAltBase, zNotFound, zFileGlob, flags) ){
3318 win32_http_server(iPort, mxPort, zBrowserCmd, zStopperFile,
3319
--- src/main.c
+++ src/main.c
@@ -2786,11 +2786,11 @@
2786 }else if( g.fSshClient & CGI_SSH_CLIENT ){
2787 ssh_request_loop(zIpAddr, glob_create(zFileGlob));
2788 }else{
2789 #if FOSSIL_ENABLE_SSL
2790 if( g.httpUseSSL ){
2791 g.httpSSLConn = ssl_new_server(0);
2792 }
2793 #endif
2794 cgi_handle_http_request(zIpAddr);
2795 }
2796 process_one_web_page(zNotFound, glob_create(zFileGlob), allowRepoList);
@@ -3286,11 +3286,11 @@
3286 }
3287 if( flags & HTTP_SERVER_SCGI ){
3288 cgi_handle_scgi_request();
3289 }else if( g.httpUseSSL ){
3290 #if FOSSIL_ENABLE_SSL
3291 g.httpSSLConn = ssl_new_server(0);
3292 #endif
3293 cgi_handle_http_request(0);
3294 }else{
3295 cgi_handle_http_request(0);
3296 }
@@ -3306,13 +3306,10 @@
3306 }
3307 #endif /* FOSSIL_ENABLE_SSL */
3308
3309 #else /* WIN32 */
3310 /* Win32 implementation */
 
 
 
3311 if( allowRepoList ){
3312 flags |= HTTP_SERVER_REPOLIST;
3313 }
3314 if( win32_http_service(iPort, zAltBase, zNotFound, zFileGlob, flags) ){
3315 win32_http_server(iPort, mxPort, zBrowserCmd, zStopperFile,
3316
+56 -18
--- src/winhttp.c
+++ src/winhttp.c
@@ -340,47 +340,72 @@
340340
FILE *in = 0, *out = 0, *aux = 0;
341341
int amt, got, i;
342342
int wanted = 0;
343343
char *z;
344344
char *zIp;
345
+ void *sslConn = 0;
345346
char zCmdFName[MAX_PATH];
346347
char zRequestFName[MAX_PATH];
347348
char zReplyFName[MAX_PATH];
348349
char zCmd[2000]; /* Command-line to process the request */
349
- char zHdr[4000]; /* The HTTP request header */
350
+ char zBuf[65536]; /* The HTTP request header */
351
+ const int szHdr = 4000; /* Reduced header size */
350352
351353
sqlite3_snprintf(MAX_PATH, zCmdFName,
352354
"%s_%06d_cmd.txt", zTempPrefix, p->id);
353355
sqlite3_snprintf(MAX_PATH, zRequestFName,
354356
"%s_%06d_in.txt", zTempPrefix, p->id);
355357
sqlite3_snprintf(MAX_PATH, zReplyFName,
356358
"%s_%06d_out.txt", zTempPrefix, p->id);
357359
amt = 0;
358
- while( amt<sizeof(zHdr) ){
359
- got = recv(p->s, &zHdr[amt], sizeof(zHdr)-1-amt, 0);
360
- if( got==SOCKET_ERROR ) goto end_request;
360
+ if( g.httpUseSSL ){
361
+#ifdef FOSSIL_ENABLE_SSL
362
+ sslConn = ssl_new_server(p->s);
363
+#endif
364
+ }
365
+ while( amt<szHdr ){
366
+ if( sslConn ){
367
+#ifdef FOSSIL_ENABLE_SSL
368
+ got = ssl_read_server(sslConn, &zBuf[amt], szHdr-amt);
369
+#endif
370
+ }else{
371
+ got = recv(p->s, &zBuf[amt], szHdr-amt, 0);
372
+ if( got==SOCKET_ERROR ) goto end_request;
373
+ }
361374
if( got==0 ){
362375
wanted = 0;
363376
break;
364377
}
365378
amt += got;
366
- zHdr[amt] = 0;
367
- z = strstr(zHdr, "\r\n\r\n");
379
+ zBuf[amt] = 0;
380
+ z = strstr(zBuf, "\r\n\r\n");
368381
if( z ){
369
- wanted = find_content_length(zHdr) + (&z[4]-zHdr) - amt;
382
+ wanted = find_content_length(zBuf) + (&z[4]-zBuf) - amt;
370383
break;
384
+ }else{
385
+ z = strstr(zBuf, "\n\n");
386
+ if( z ){
387
+ wanted = find_content_length(zBuf) + (&z[2]-zBuf) - amt;
388
+ break;
389
+ }
371390
}
372391
}
373
- if( amt>=sizeof(zHdr) ) goto end_request;
392
+ if( amt>=szHdr ) goto end_request;
374393
out = fossil_fopen(zRequestFName, "wb");
375394
if( out==0 ) goto end_request;
376
- fwrite(zHdr, 1, amt, out);
395
+ fwrite(zBuf, 1, amt, out);
377396
while( wanted>0 ){
378
- got = recv(p->s, zHdr, sizeof(zHdr), 0);
379
- if( got==SOCKET_ERROR ) goto end_request;
380
- if( got ){
381
- fwrite(zHdr, 1, got, out);
397
+ if( sslConn ){
398
+#ifdef FOSSIL_ENABLE_SSL
399
+ got = ssl_read_server(sslConn, zBuf, sizeof(zBuf));
400
+#endif
401
+ }else{
402
+ got = recv(p->s, zBuf, sizeof(zBuf), 0);
403
+ if( got==SOCKET_ERROR ) goto end_request;
404
+ }
405
+ if( got>0 ){
406
+ fwrite(zBuf, 1, got, out);
382407
}else{
383408
break;
384409
}
385410
wanted -= got;
386411
}
@@ -405,28 +430,40 @@
405430
aux = fossil_fopen(zCmdFName, "wb");
406431
if( aux==0 ) goto end_request;
407432
fwrite(zCmd, 1, strlen(zCmd), aux);
408433
409434
sqlite3_snprintf(sizeof(zCmd), zCmd,
410
- "\"%s\" http -args \"%s\" --nossl%s",
411
- g.nameOfExe, zCmdFName, p->zOptions
435
+ "\"%s\" http -args \"%s\"%s%s",
436
+ g.nameOfExe, zCmdFName,
437
+ g.httpUseSSL ? "" : " --nossl", p->zOptions
412438
);
413439
in = fossil_fopen(zReplyFName, "w+b");
414440
fflush(out);
415441
fflush(aux);
416442
fossil_system(zCmd);
417443
if( in ){
418
- while( (got = fread(zHdr, 1, sizeof(zHdr), in))>0 ){
419
- send(p->s, zHdr, got, 0);
444
+ while( (got = fread(zBuf, 1, sizeof(zBuf), in))>0 ){
445
+ if( sslConn ){
446
+#ifdef FOSSIL_ENABLE_SSL
447
+ ssl_write_server(sslConn, zBuf, got);
448
+#endif
449
+ }else{
450
+ send(p->s, zBuf, got, 0);
451
+ }
420452
}
421453
}
422454
423455
end_request:
424456
if( out ) fclose(out);
425457
if( aux ) fclose(aux);
426458
if( in ) fclose(in);
427459
/* Initiate shutdown prior to closing the socket */
460
+ if( sslConn!=0 ){
461
+#ifdef FOSSIL_ENABLE_SSL
462
+ ssl_close_server(sslConn);
463
+#endif
464
+ }
428465
if( shutdown(p->s,1)==0 ) shutdown(p->s,0);
429466
closesocket(p->s);
430467
/* Make multiple attempts to delete the temporary files. Sometimes AV
431468
** software keeps the files open for a few seconds, preventing the file
432469
** from being deleted on the first try. */
@@ -619,11 +656,12 @@
619656
}
620657
zTempPrefix = mprintf("%sfossil_server_P%d",
621658
fossil_unicode_to_utf8(zTmpPath), iPort);
622659
fossil_print("Temporary files: %s*\n", zTempPrefix);
623660
fossil_print("Listening for %s requests on TCP port %d\n",
624
- (flags&HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort);
661
+ (flags&HTTP_SERVER_SCGI)!=0 ? "SCGI" :
662
+ g.httpUseSSL ? "TLS-encrypted HTTPS" : "HTTP", iPort);
625663
if( zBrowser ){
626664
zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort);
627665
fossil_print("Launch webbrowser: %s\n", zBrowser);
628666
fossil_system(zBrowser);
629667
}
630668
--- src/winhttp.c
+++ src/winhttp.c
@@ -340,47 +340,72 @@
340 FILE *in = 0, *out = 0, *aux = 0;
341 int amt, got, i;
342 int wanted = 0;
343 char *z;
344 char *zIp;
 
345 char zCmdFName[MAX_PATH];
346 char zRequestFName[MAX_PATH];
347 char zReplyFName[MAX_PATH];
348 char zCmd[2000]; /* Command-line to process the request */
349 char zHdr[4000]; /* The HTTP request header */
 
350
351 sqlite3_snprintf(MAX_PATH, zCmdFName,
352 "%s_%06d_cmd.txt", zTempPrefix, p->id);
353 sqlite3_snprintf(MAX_PATH, zRequestFName,
354 "%s_%06d_in.txt", zTempPrefix, p->id);
355 sqlite3_snprintf(MAX_PATH, zReplyFName,
356 "%s_%06d_out.txt", zTempPrefix, p->id);
357 amt = 0;
358 while( amt<sizeof(zHdr) ){
359 got = recv(p->s, &zHdr[amt], sizeof(zHdr)-1-amt, 0);
360 if( got==SOCKET_ERROR ) goto end_request;
 
 
 
 
 
 
 
 
 
 
 
361 if( got==0 ){
362 wanted = 0;
363 break;
364 }
365 amt += got;
366 zHdr[amt] = 0;
367 z = strstr(zHdr, "\r\n\r\n");
368 if( z ){
369 wanted = find_content_length(zHdr) + (&z[4]-zHdr) - amt;
370 break;
 
 
 
 
 
 
371 }
372 }
373 if( amt>=sizeof(zHdr) ) goto end_request;
374 out = fossil_fopen(zRequestFName, "wb");
375 if( out==0 ) goto end_request;
376 fwrite(zHdr, 1, amt, out);
377 while( wanted>0 ){
378 got = recv(p->s, zHdr, sizeof(zHdr), 0);
379 if( got==SOCKET_ERROR ) goto end_request;
380 if( got ){
381 fwrite(zHdr, 1, got, out);
 
 
 
 
 
 
382 }else{
383 break;
384 }
385 wanted -= got;
386 }
@@ -405,28 +430,40 @@
405 aux = fossil_fopen(zCmdFName, "wb");
406 if( aux==0 ) goto end_request;
407 fwrite(zCmd, 1, strlen(zCmd), aux);
408
409 sqlite3_snprintf(sizeof(zCmd), zCmd,
410 "\"%s\" http -args \"%s\" --nossl%s",
411 g.nameOfExe, zCmdFName, p->zOptions
 
412 );
413 in = fossil_fopen(zReplyFName, "w+b");
414 fflush(out);
415 fflush(aux);
416 fossil_system(zCmd);
417 if( in ){
418 while( (got = fread(zHdr, 1, sizeof(zHdr), in))>0 ){
419 send(p->s, zHdr, got, 0);
 
 
 
 
 
 
420 }
421 }
422
423 end_request:
424 if( out ) fclose(out);
425 if( aux ) fclose(aux);
426 if( in ) fclose(in);
427 /* Initiate shutdown prior to closing the socket */
 
 
 
 
 
428 if( shutdown(p->s,1)==0 ) shutdown(p->s,0);
429 closesocket(p->s);
430 /* Make multiple attempts to delete the temporary files. Sometimes AV
431 ** software keeps the files open for a few seconds, preventing the file
432 ** from being deleted on the first try. */
@@ -619,11 +656,12 @@
619 }
620 zTempPrefix = mprintf("%sfossil_server_P%d",
621 fossil_unicode_to_utf8(zTmpPath), iPort);
622 fossil_print("Temporary files: %s*\n", zTempPrefix);
623 fossil_print("Listening for %s requests on TCP port %d\n",
624 (flags&HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort);
 
625 if( zBrowser ){
626 zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort);
627 fossil_print("Launch webbrowser: %s\n", zBrowser);
628 fossil_system(zBrowser);
629 }
630
--- src/winhttp.c
+++ src/winhttp.c
@@ -340,47 +340,72 @@
340 FILE *in = 0, *out = 0, *aux = 0;
341 int amt, got, i;
342 int wanted = 0;
343 char *z;
344 char *zIp;
345 void *sslConn = 0;
346 char zCmdFName[MAX_PATH];
347 char zRequestFName[MAX_PATH];
348 char zReplyFName[MAX_PATH];
349 char zCmd[2000]; /* Command-line to process the request */
350 char zBuf[65536]; /* The HTTP request header */
351 const int szHdr = 4000; /* Reduced header size */
352
353 sqlite3_snprintf(MAX_PATH, zCmdFName,
354 "%s_%06d_cmd.txt", zTempPrefix, p->id);
355 sqlite3_snprintf(MAX_PATH, zRequestFName,
356 "%s_%06d_in.txt", zTempPrefix, p->id);
357 sqlite3_snprintf(MAX_PATH, zReplyFName,
358 "%s_%06d_out.txt", zTempPrefix, p->id);
359 amt = 0;
360 if( g.httpUseSSL ){
361 #ifdef FOSSIL_ENABLE_SSL
362 sslConn = ssl_new_server(p->s);
363 #endif
364 }
365 while( amt<szHdr ){
366 if( sslConn ){
367 #ifdef FOSSIL_ENABLE_SSL
368 got = ssl_read_server(sslConn, &zBuf[amt], szHdr-amt);
369 #endif
370 }else{
371 got = recv(p->s, &zBuf[amt], szHdr-amt, 0);
372 if( got==SOCKET_ERROR ) goto end_request;
373 }
374 if( got==0 ){
375 wanted = 0;
376 break;
377 }
378 amt += got;
379 zBuf[amt] = 0;
380 z = strstr(zBuf, "\r\n\r\n");
381 if( z ){
382 wanted = find_content_length(zBuf) + (&z[4]-zBuf) - amt;
383 break;
384 }else{
385 z = strstr(zBuf, "\n\n");
386 if( z ){
387 wanted = find_content_length(zBuf) + (&z[2]-zBuf) - amt;
388 break;
389 }
390 }
391 }
392 if( amt>=szHdr ) goto end_request;
393 out = fossil_fopen(zRequestFName, "wb");
394 if( out==0 ) goto end_request;
395 fwrite(zBuf, 1, amt, out);
396 while( wanted>0 ){
397 if( sslConn ){
398 #ifdef FOSSIL_ENABLE_SSL
399 got = ssl_read_server(sslConn, zBuf, sizeof(zBuf));
400 #endif
401 }else{
402 got = recv(p->s, zBuf, sizeof(zBuf), 0);
403 if( got==SOCKET_ERROR ) goto end_request;
404 }
405 if( got>0 ){
406 fwrite(zBuf, 1, got, out);
407 }else{
408 break;
409 }
410 wanted -= got;
411 }
@@ -405,28 +430,40 @@
430 aux = fossil_fopen(zCmdFName, "wb");
431 if( aux==0 ) goto end_request;
432 fwrite(zCmd, 1, strlen(zCmd), aux);
433
434 sqlite3_snprintf(sizeof(zCmd), zCmd,
435 "\"%s\" http -args \"%s\"%s%s",
436 g.nameOfExe, zCmdFName,
437 g.httpUseSSL ? "" : " --nossl", p->zOptions
438 );
439 in = fossil_fopen(zReplyFName, "w+b");
440 fflush(out);
441 fflush(aux);
442 fossil_system(zCmd);
443 if( in ){
444 while( (got = fread(zBuf, 1, sizeof(zBuf), in))>0 ){
445 if( sslConn ){
446 #ifdef FOSSIL_ENABLE_SSL
447 ssl_write_server(sslConn, zBuf, got);
448 #endif
449 }else{
450 send(p->s, zBuf, got, 0);
451 }
452 }
453 }
454
455 end_request:
456 if( out ) fclose(out);
457 if( aux ) fclose(aux);
458 if( in ) fclose(in);
459 /* Initiate shutdown prior to closing the socket */
460 if( sslConn!=0 ){
461 #ifdef FOSSIL_ENABLE_SSL
462 ssl_close_server(sslConn);
463 #endif
464 }
465 if( shutdown(p->s,1)==0 ) shutdown(p->s,0);
466 closesocket(p->s);
467 /* Make multiple attempts to delete the temporary files. Sometimes AV
468 ** software keeps the files open for a few seconds, preventing the file
469 ** from being deleted on the first try. */
@@ -619,11 +656,12 @@
656 }
657 zTempPrefix = mprintf("%sfossil_server_P%d",
658 fossil_unicode_to_utf8(zTmpPath), iPort);
659 fossil_print("Temporary files: %s*\n", zTempPrefix);
660 fossil_print("Listening for %s requests on TCP port %d\n",
661 (flags&HTTP_SERVER_SCGI)!=0 ? "SCGI" :
662 g.httpUseSSL ? "TLS-encrypted HTTPS" : "HTTP", iPort);
663 if( zBrowser ){
664 zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort);
665 fossil_print("Launch webbrowser: %s\n", zBrowser);
666 fossil_system(zBrowser);
667 }
668

Keyboard Shortcuts

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