Skip to content
This repository has been archived by the owner on Sep 4, 2024. It is now read-only.

simple_http: when writing fails, try (once) to reconnect the socket #84

Merged
merged 3 commits into from
Jan 30, 2023

Conversation

apoelstra
Copy link
Owner

@apoelstra apoelstra commented Jan 25, 2023

Attempt at #79. Does not fix the issue, but will merge this anyway since it fixes an issue I've hit in other projects.

**write_sock.get_mut() = self.fresh_socket()?;
write_sock.write_all(b"POST ")?;
}
write_sock.write_all(b"POST ")?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the second write of "POST" (excluding the error path)? At this stage we've either written POST already or returned an error?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, derp, this second POST should not be there and probably completely breaks things. Pushed to remove it.

Copy link
Collaborator

@tcharding tcharding left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 5b7b23c

@apoelstra apoelstra merged commit bba20ad into master Jan 30, 2023
@apoelstra apoelstra deleted the 2023-01--detect-epipe branch January 30, 2023 15:33
apoelstra added a commit that referenced this pull request Mar 20, 2023
0de1c58 simple_http: unit test to demonstrate detecting broken pipe (Philip Robinson)
0cab08a simple_http: add second send attempt if read indicates socket is broken (Philip Robinson)

Pull request description:

  While upgrading from v0.11 to v0.14 I noticed that I started getting the following error when the server had disconnected the socket between requests, in our case due to the server idle timeout:
  ```
  Err(Transport(HttpResponseTooShort { actual: 0, needed: 12 }))
  ```
  The same issue as is reported in #79 I believe.

  I noticed #84 was an attempt to solve the problem and I think I found out why it didn't work as expected.

  The client is using a `BufWriter` to write the `TcpStream` and unless you flush the buffer you will not see the broken pipe error in time in order to request a fresh connection.

  This PR adds in the flushes and provides a unit test demonstrating that it fixes the issue. If you comment out the flushes you will see the symptom reported in #79.

  ## Revision
  The first approach of flushing the write buffer twice during the POST angered HTTP servers that expected the request to be contained in a single message.

  The revised approach uses the method that is advocated in the unix docs to detect a broken TCP stream which is that if the blocking `read` operation returns 0 bytes then the socket is closed. So this PR creates a buffer to hold the request, attempts to send it and then reads the response. If the response was length 0 it will attempt to get a fresh socket and send the request a second time.

ACKs for top commit:
  apoelstra:
    ACK 0de1c58

Tree-SHA512: 0871a0c57b3d63b2d7b0ebd4bb1bb2f4f68bb88b7fe55fa8f3566f49fbd3aa33920e7e953e50320797bf2b1791ea223e6ef40f57901fbc3908a005e3ea167f77
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants