Search code examples
c++qtqtnetwork

Resending a post/put request without having the original data


I have a question that has been stumping me recently. I am creating a simple web browser to interact with a single website for user management of a product. The issue that I am currently having is this: A user can upload a new file though the ui with a basic web form. Upon selecting to upload, the request will fail with an error code of 205, which is:

QNetworkReply::ContentReSendError - the request needed to be sent again, but this failed for example because the upload data could not be read a second time.

If the user attempts to upload again, the file will upload without error. To fix this, I would like to detect if there was an error, and if so, resend the request.

My issue is that I don't have the data to go with the request. I can retrieve the request itself, but not the data. I imagine my solution to look like the nested if in this stack overflow question:

if((reply->error() == QNetworkReply::TemporaryNetworkFailureError) || (reply->error() == QNetworkReply::ContentReSendError)) {
     // retry the last request
     _reply = accessManager.put(reply->request(), _currentItem);
}

However, this user has access to the _currentItem because they created the request originally in their program, while mine is being created on the fly. Is there some way that I can capture the data being sent, or cache it? I had hoped that the QNetworkAccessManager stored previous requests for an easy retry, but I am not seeing anything like that. Thanks for any insight and help!

EDIT

For clarification: is there anyway to use a QNetworkAccessManager to get both the request and data for a post/put that was not defined in the program.


Solution

  • Yes, there are two ways, but as-is the feature doesn't exist.

    1. Edit Qt's source code to add it directly to QNetworkAccessManager, or

    2. Implement it as a caching-only HTTP proxy that runs in the same process. The proxy's implementation can use a nested QNetworkAccessManager to execute the requests on the real network. The implementation would need to decode the incoming request, re-build the QNetworkRequest header, and pass it to the nested manager along with any of request's data. At that point you can set aside the data, and implement a retry at the proxy level.

    It'd be probably less work and hassle to implement option 1, but some projects are irrationally averse to modifying Qt, so I'll put option 2 out there for such cases.