Fossil

Check-in [9110662f]
Login

Check-in [9110662f]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Swapped semantics of the new argument to ssl_read_server(), per forum discussion. Adjacent doc touchups.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | ssl-read-loops2
Files: files | file ages | folders
SHA3-256: 9110662fd1bb201c89d2f295d0aa469fb345dd43abf08907a961c1a567a660ef
User & Date: stephan 2022-01-28 14:51:32
Context
2022-01-28
17:36
Improved TLS read-from-client support on Windows. ... (check-in: b0834be5 user: stephan tags: trunk)
14:51
Swapped semantics of the new argument to ssl_read_server(), per forum discussion. Adjacent doc touchups. ... (Closed-Leaf check-in: 9110662f user: stephan tags: ssl-read-loops2)
06:37
Minor code style fixes. ... (check-in: d4ef6153 user: florian tags: ssl-read-loops2)
Changes
Unified Diff Ignore Whitespace Patch Hide diffs
Changes to src/cgi.c.
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
  fossil_fatal("SSL not available");
#endif
}

/* Works like fread():
**
** Read as many as bytes of content as we can, up to a maximum of nmemb
** bytes.  Return the number of bytes read.  Return -1 if there is no
** further input or if an I/O error occurs.
*/
size_t cgi_fread(void *ptr, size_t nmemb){
  if( !g.httpUseSSL ){
    return fread(ptr, 1, nmemb, g.httpIn);
  }
#ifdef FOSSIL_ENABLE_SSL
  return ssl_read_server(g.httpSSLConn, ptr, nmemb, 0);
#else
  fossil_fatal("SSL not available");
#endif
}

/* Works like feof():
**






|







|







362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
  fossil_fatal("SSL not available");
#endif
}

/* Works like fread():
**
** Read as many as bytes of content as we can, up to a maximum of nmemb
** bytes.  Return the number of bytes read.  Return 0 if there is no
** further input or if an I/O error occurs.
*/
size_t cgi_fread(void *ptr, size_t nmemb){
  if( !g.httpUseSSL ){
    return fread(ptr, 1, nmemb, g.httpIn);
  }
#ifdef FOSSIL_ENABLE_SSL
  return ssl_read_server(g.httpSSLConn, ptr, nmemb, 1);
#else
  fossil_fatal("SSL not available");
#endif
}

/* Works like feof():
**
Changes to src/http_ssl.c.
809
810
811
812
813
814
815

816
817

818




819
820
821
822
823
824
825
826
827
828
829
830
831
832

833

834
835
836
837
838
839


840
841
842
843
844
845
846
  SslServerConn *pServer = (SslServerConn*)pServerArg;
  return BIO_eof(pServer->bio);
}

/*
** Read cleartext bytes that have been received from the client and
** decrypted by the SSL server codec.

** If the expected payload size unknown, i.e. if the HTTP Content-Length: header
** field has not been parsed, the noLoop argument should be 1, or SSL_read() may

** block and wait for more data than is eventually going to arrive (on Windows).




*/
size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf, int noLoop){
  int n;
  size_t rc = 0;
  SslServerConn *pServer = (SslServerConn*)pServerArg;
  if( nBuf>0x7fffffff ){ fossil_fatal("SSL read too big"); }
  else if( BIO_eof(pServer->bio) ) return 0;
  while( nBuf!=rc ){
    n = SSL_read(pServer->ssl, zBuf + rc, (int)(nBuf - rc));
    if( n<=0 ){
      break;
    }else if(n>0){
      rc += n;
    }

    if( noLoop ) break;

  }
  return rc;
}

/*
** Read a single line of text from the client.


*/
char *ssl_gets(void *pServerArg, char *zBuf, int nBuf){
  int n = 0;
  int i;
  SslServerConn *pServer = (SslServerConn*)pServerArg;

  if( BIO_eof(pServer->bio) ) return 0;






>
|
|
>
|
>
>
>
>

|




<
|

|
<
<


>
|
>





|
>
>







809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830

831
832
833


834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
  SslServerConn *pServer = (SslServerConn*)pServerArg;
  return BIO_eof(pServer->bio);
}

/*
** Read cleartext bytes that have been received from the client and
** decrypted by the SSL server codec.
**
** If the expected payload size unknown, i.e. if the HTTP
** Content-Length: header field has not been parsed, the doLoop
** argument should be 0, or SSL_read() may block and wait for more
** data than is eventually going to arrive (on Windows). On
** non-Windows builds, it has been our experience that the final
** argument must always be true, as discussed at length at:
**
** https://fossil-scm.org/forum/forumpost/2f818850abb72719
*/
size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf, int doLoop){
  int n;
  size_t rc = 0;
  SslServerConn *pServer = (SslServerConn*)pServerArg;
  if( nBuf>0x7fffffff ){ fossil_fatal("SSL read too big"); }

  while( nBuf!=rc && BIO_eof(pServer->bio)==0 ){
    n = SSL_read(pServer->ssl, zBuf + rc, (int)(nBuf - rc));
    if( n>0 ){


      rc += n;
    }
    if( doLoop==0 || n<=0 ){
      break;
    }
  }
  return rc;
}

/*
** Read a single line of text from the client, up to nBuf-1 bytes. On
** success, writes nBuf-1 bytes to zBuf and NUL-terminates zBuf.
** Returns NULL on an I/O error or at EOF.
*/
char *ssl_gets(void *pServerArg, char *zBuf, int nBuf){
  int n = 0;
  int i;
  SslServerConn *pServer = (SslServerConn*)pServerArg;

  if( BIO_eof(pServer->bio) ) return 0;
Changes to src/winhttp.c.
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
#ifdef FOSSIL_ENABLE_SSL
    sslConn = ssl_new_server(p->s);
#endif
  }
  while( amt<szHdr ){
    if( sslConn ){
#ifdef FOSSIL_ENABLE_SSL
      got = ssl_read_server(sslConn, &zBuf[amt], szHdr-1-amt, 1);
#endif
    }else{
      got = recv(p->s, &zBuf[amt], szHdr-1-amt, 0);
      if( got==SOCKET_ERROR ) goto end_request;
    }
    if( got==0 ){
      wanted = 0;






|







361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
#ifdef FOSSIL_ENABLE_SSL
    sslConn = ssl_new_server(p->s);
#endif
  }
  while( amt<szHdr ){
    if( sslConn ){
#ifdef FOSSIL_ENABLE_SSL
      got = ssl_read_server(sslConn, &zBuf[amt], szHdr-1-amt, 0);
#endif
    }else{
      got = recv(p->s, &zBuf[amt], szHdr-1-amt, 0);
      if( got==SOCKET_ERROR ) goto end_request;
    }
    if( got==0 ){
      wanted = 0;
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
  if( amt>=szHdr ) goto end_request;
  out = fossil_fopen(zRequestFName, "wb");
  if( out==0 ) goto end_request;
  fwrite(zBuf, 1, amt, out);
  while( wanted>0 ){
    if( sslConn ){
#ifdef FOSSIL_ENABLE_SSL
      got = ssl_read_server(sslConn, zBuf, min(wanted, sizeof(zBuf)), 0);
#endif
    }else{
      got = recv(p->s, zBuf, sizeof(zBuf), 0);
      if( got==SOCKET_ERROR ) goto end_request;
    }
    if( got>0 ){
      fwrite(zBuf, 1, got, out);






|







392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
  if( amt>=szHdr ) goto end_request;
  out = fossil_fopen(zRequestFName, "wb");
  if( out==0 ) goto end_request;
  fwrite(zBuf, 1, amt, out);
  while( wanted>0 ){
    if( sslConn ){
#ifdef FOSSIL_ENABLE_SSL
      got = ssl_read_server(sslConn, zBuf, min(wanted, sizeof(zBuf)), 1);
#endif
    }else{
      got = recv(p->s, zBuf, sizeof(zBuf), 0);
      if( got==SOCKET_ERROR ) goto end_request;
    }
    if( got>0 ){
      fwrite(zBuf, 1, got, out);