git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v2 1/2] Change how HTTP response body is returned

From
Jeff King <peff@peff.net>
Date
Jan 4, 2019, 10:11 UTC
Message-ID
<20190104101149.GA26185@sigill.intra.peff.net>
In-Reply-To
<xmqqtviph835.fsf@gitster-ct.c.googlers.com>
On Thu, Jan 03, 2019 at 11:09:02AM -0800, Junio C Hamano wrote:
Show 19 quoted lines
> > +	if (dest->file) {
> > +		/*
> > +		 * At this point, the file contains the response body of the
> > +		 * previous request. We need to truncate the file.
> > +		 */
> > +		FILE *new_file = freopen(dest->filename, "w", dest->file);
> 
> Now freopen() lets us restart the file anew with a new "FILE *".
> 
> > +		if (new_file == NULL) {
> > +			error("Unable to open local file %s", dest->filename);
> 
> error_errno(), perhaps?
> 
> At this point, I presume that dest->file is closed by the failed
> freopen(), but dest->file is still non-NULL and causes further calls
> to http_request() with this dest would be a disaster?  As long as
> the caller of this function reacts to HTTP_ERROR and kill the dest,
> it would be fine.

I also wondered what timing guarantees freopen() gives us (i.e., is it possible for it to open and truncate the file, and then close the old handle, flushing some in-memory buffer). C99 says:

  The freopen function first attempts to close any file that is
  associated with the specified stream. Failure to close the file is
  ignored. The error and end-of-file indicators for the stream are
  cleared.

So I think the order is OK for my concern, but not for yours. I.e., on an error, dest->file is now undefined.

It might be nice to set "dest->file == NULL" in that case. There's no guarantee that the caller did not hold onto its own copy of the handle, but since this struct is only exposed internally within http.c, that's probably OK.

The most robust thing would perhaps be:
  fflush(dest->file);
  ftruncate(fileno(dest->file), 0);
which leaves the handle intact.

(I agree with the rest of your review, especially that it would be easier to read if this were split into separate refactor and change-behavior steps).

-Peff
Previous: Junio C HamanoNext: Junio C Hamano
Message 10 of 29 in “Change how HTTP response body is returned”
  1. 1/2 Change how HTTP response body is returnedMasaya Suzuki, Dec 28, 2018
  2. 2/2 Unset CURLOPT_FAILONERRORMasaya Suzuki, Dec 28, 2018
  3. Eric SunshineDec 28, 2018
  4. Masaya SuzukiDec 28, 2018
  5. Eric SunshineDec 28, 2018
  6. Masaya SuzukiDec 28, 2018
  7. 0/2 Show HTTP headers of failed requests with GIT_CURL_VERBOSEMasaya Suzuki, Dec 29, 2018
  8. 1/2 Change how HTTP response body is returnedMasaya Suzuki, Dec 29, 2018
  9. Junio C HamanoJan 3, 2019
  10. Jeff KingJan 4, 2019
  11. Junio C HamanoJan 4, 2019
  12. Jeff KingJan 4, 2019
  13. 2/2 Unset CURLOPT_FAILONERRORMasaya Suzuki, Dec 29, 2018
  14. Jeff KingJan 4, 2019
  15. Masaya SuzukiJan 7, 2019
  16. 0/5 Show HTTP headers of failed requests with GIT_CURL_VERBOSEMasaya Suzuki, Jan 8, 2019
  17. 1/5 http: support file handles for HTTP_KEEP_ERRORMasaya Suzuki, Jan 8, 2019
  18. SZEDER GáborJan 9, 2019
  19. 2/5 http: enable keep_error for HTTP requestsMasaya Suzuki, Jan 8, 2019
  20. 3/5 remote-curl: define struct for CURLOPT_WRITEFUNCTIONMasaya Suzuki, Jan 8, 2019
  21. 4/5 remote-curl: unset CURLOPT_FAILONERRORMasaya Suzuki, Jan 8, 2019
  22. 5/5 test: test GIT_CURL_VERBOSE=1 shows an errorMasaya Suzuki, Jan 8, 2019
  23. 0/5 Show HTTP headers of failed requests with GIT_CURL_VERBOSEMasaya Suzuki, Jan 10, 2019
  24. 1/5 http: support file handles for HTTP_KEEP_ERRORMasaya Suzuki, Jan 10, 2019
  25. 2/5 http: enable keep_error for HTTP requestsMasaya Suzuki, Jan 10, 2019
  26. 3/5 remote-curl: define struct for CURLOPT_WRITEFUNCTIONMasaya Suzuki, Jan 10, 2019
  27. 4/5 remote-curl: unset CURLOPT_FAILONERRORMasaya Suzuki, Jan 10, 2019
  28. 5/5 test: test GIT_CURL_VERBOSE=1 shows an errorMasaya Suzuki, Jan 10, 2019
  29. Junio C HamanoJan 10, 2019

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.