Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

http: Report errors reading discs #11700

Merged
merged 3 commits into from
Dec 27, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
http: Add timeout on no response.
Firewalls can cause this, by opening a connection but never responding.
  • Loading branch information
unknownbrackets committed Dec 27, 2018
commit 359afb2d6b6f170c53460d01fd39963f5c51c136
5 changes: 4 additions & 1 deletion Core/FileLoaders/HTTPFileLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,20 @@ HTTPFileLoader::HTTPFileLoader(const std::string &filename)
void HTTPFileLoader::Prepare() {
std::call_once(preparedFlag_, [this](){
if (!client_.Resolve(url_.Host().c_str(), url_.Port())) {
// TODO: Should probably set some flag?
ERROR_LOG(LOADER, "HTTP request failed, unable to resolve: %s port %d", url_.Host().c_str(), url_.Port());
return;
}

client_.SetDataTimeout(20.0);
Connect();
if (!connected_) {
ERROR_LOG(LOADER, "HTTP request failed, failed to connect: %s port %d", url_.Host().c_str(), url_.Port());
return;
}

int err = client_.SendRequest("HEAD", url_.Resource().c_str());
if (err < 0) {
ERROR_LOG(LOADER, "HTTP request failed, failed to send request: %s port %d", url_.Host().c_str(), url_.Port());
Disconnect();
return;
}
Expand Down
8 changes: 6 additions & 2 deletions ext/native/base/buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,12 @@ bool Buffer::FlushToFile(const char *filename) {
return true;
}

bool Buffer::FlushSocket(uintptr_t sock) {
bool Buffer::FlushSocket(uintptr_t sock, double timeout) {
for (size_t pos = 0, end = data_.size(); pos < end; ) {
if (timeout >= 0.0 && !fd_util::WaitUntilReady(sock, timeout, true)) {
ELOG("FlushSocket timed out");
return false;
}
int sent = send(sock, &data_[pos], (int)(end - pos), MSG_NOSIGNAL);
if (sent < 0) {
ELOG("FlushSocket failed");
Expand All @@ -156,7 +160,7 @@ bool Buffer::FlushSocket(uintptr_t sock) {
pos += sent;

// Buffer full, don't spin.
if (sent == 0) {
if (sent == 0 && timeout < 0.0) {
sleep_ms(1);
}
}
Expand Down
8 changes: 4 additions & 4 deletions ext/native/base/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ class Buffer {

// Simple I/O.

// Writes the entire buffer to the file descriptor. Also resets the
// size to zero. On failure, data remains in buffer and nothing is
// written.
// Writes the entire buffer to the file descriptor. Also resets the
// size to zero. On failure, data remains in buffer and nothing is
// written.
bool Flush(int fd);
bool FlushToFile(const char *filename);
bool FlushSocket(uintptr_t sock); // Windows portability
bool FlushSocket(uintptr_t sock, double timeout = -1.0); // Windows portability

bool ReadAll(int fd, int hintSize = 0);
bool ReadAllWithProgress(int fd, int knownSize, float *progress, bool *cancelled);
Expand Down
6 changes: 5 additions & 1 deletion ext/native/net/http_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ int Client::SendRequestWithData(const char *method, const char *resource, const
userAgent_,
otherHeaders ? otherHeaders : "");
buffer.Append(data);
bool flushed = buffer.FlushSocket(sock());
bool flushed = buffer.FlushSocket(sock(), dataTimeout_);
if (!flushed) {
return -1; // TODO error code.
}
Expand All @@ -292,6 +292,10 @@ int Client::SendRequestWithData(const char *method, const char *resource, const

int Client::ReadResponseHeaders(Buffer *readbuf, std::vector<std::string> &responseHeaders, float *progress) {
// Snarf all the data we can into RAM. A little unsafe but hey.
if (dataTimeout_ >= 0.0 && fd_util::WaitUntilReady(sock(), dataTimeout_, false)) {
ELOG("HTTP headers timed out");
return -1;
}
if (readbuf->Read(sock(), 4096) < 0) {
ELOG("Failed to read HTTP headers :(");
return -1;
Expand Down
6 changes: 6 additions & 0 deletions ext/native/net/http_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,14 @@ class Client : public net::Connection {
// If your response contains a response, you must read it.
int ReadResponseEntity(Buffer *readbuf, const std::vector<std::string> &responseHeaders, Buffer *output, float *progress = nullptr, bool *cancelled = nullptr);

void SetDataTimeout(double t) {
dataTimeout_ = t;
}

protected:
const char *userAgent_;
const char *httpVersion_;
double dataTimeout_ = -1.0;
};

// Not particularly efficient, but hey - it's a background download, that's pretty cool :P
Expand Down