Skip to content

Commit

Permalink
Linux: fixing the network issues (#707)
Browse files Browse the repository at this point in the history
  • Loading branch information
zero-meta authored Jun 11, 2024
1 parent 85a4baa commit 0d676ea
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 13 deletions.
60 changes: 56 additions & 4 deletions platform/linux/src/NetworkLibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#include "NetworkLibrary.h"
#include "NetworkSupport.h"

using namespace Rtt;

int luaload_network(lua_State *L);

// This corresponds to the name of the library, e.g. [Lua] require "plugin.library"
Expand Down Expand Up @@ -71,6 +73,9 @@ void NetworkNotifierTask::operator()( Scheduler & sender )
fRequestState->setError(message);
}

// Set responseHeaders
fRequestState->setResponseHeaders(fRequestParams->fResponseHeaders.c_str());

CoronaFileSpec *responseFile = fRequestParams->getResponseFile();
if (responseFile != NULL)
{
Expand All @@ -85,6 +90,8 @@ void NetworkNotifierTask::operator()( Scheduler & sender )
{
fwrite(fRequestParams->fResponse.data(), 1, fRequestParams->fResponse.size(), f);
fclose(f);
fRequestState->setBytesEstimated(fRequestParams->fResponse.size());
fRequestState->setBytesTransferred(fRequestParams->fResponse.size());
}
}
}
Expand All @@ -93,6 +100,8 @@ void NetworkNotifierTask::operator()( Scheduler & sender )
fRequestState->fResponseBody.bodyType = TYPE_BYTES;
const uint8_t* buf = (const uint8_t*) fRequestParams->fResponse.data();
fRequestState->fResponseBody.bodyBytes = new ByteVector(buf, buf + fRequestParams->fResponse.size());
fRequestState->setBytesEstimated(fRequestParams->fResponse.size());
fRequestState->setBytesTransferred(fRequestParams->fResponse.size());
}

fRequestState->setStatus(status);
Expand Down Expand Up @@ -182,7 +191,7 @@ int NetworkLibrary::Open(lua_State *L)

// Leave "library" on top of stack
// Set library as upvalue for each library function
lua_CFunction factory = Corona::Lua::Open < Rtt::luaload_network > ;
lua_CFunction factory = Corona::Lua::Open < luaload_network > ;
return CoronaLibraryNewWithFactory(L, factory, kVTable, library);
}

Expand Down Expand Up @@ -221,6 +230,15 @@ int NetworkLibrary::request(lua_State *L)
return thiz->sendRequest(L);
}

size_t curlHeaderCallback(char *buffer, size_t size, size_t nitems, void *userdata) {
size_t totalSize = size * nitems;

UTF8String *headers = static_cast<UTF8String *>(userdata);
headers->append(buffer, totalSize);

return totalSize;
}

int NetworkLibrary::sendRequest(lua_State *L)
{
smart_ptr<NetworkRequestParameters> requestParams = new NetworkRequestParameters(L);
Expand All @@ -233,10 +251,11 @@ int NetworkLibrary::sendRequest(lua_State *L)
curl_multi_add_handle(curlMulti, curl);

requestParams->setCURL(curlMulti, curl);
const std::string& method = requestParams->getRequestMethod();
// const std::string& method = requestParams->getRequestMethod();

CURLcode rc;
const Body* body = requestParams->getRequestBody();
std::string fileSize = "";
switch (body->bodyType)
{
case TYPE_STRING:
Expand All @@ -249,13 +268,32 @@ int NetworkLibrary::sendRequest(lua_State *L)
}
case TYPE_BYTES:
{
Rtt_ASSERT(body->bodyString);
Rtt_ASSERT(body->bodyBytes);
unsigned char* buf = &body->bodyBytes->operator[](0);
long buflen = body->bodyBytes->size();
rc = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, buf);
rc = curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, buflen);
break;
}
case TYPE_FILE:
{
Rtt_ASSERT(body->bodyFile);
FILE *uploadFile = fopen(body->bodyFile->getFullPath().c_str(), "rb");
if (uploadFile == NULL) {
break;
}
// Record the file handle, to be cleaned up together with curl.
requestParams->setFileHandle(uploadFile);
rc = curl_easy_setopt(curl, CURLOPT_READDATA, uploadFile);
// Get and set the file size.
long size = fseek(uploadFile, 0, SEEK_END) ? -1 : ftell(uploadFile);
fseek(uploadFile, 0, SEEK_SET);
rc = curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)size);
fileSize = "Content-Length: " + std::to_string(size);
// Set the POST request.
rc = curl_easy_setopt(curl, CURLOPT_POST, 1L);
break;
}
case TYPE_NONE:
break;

Expand All @@ -276,7 +314,16 @@ int NetworkLibrary::sendRequest(lua_State *L)
UTF8String requestHeaders = key + ": " + value;
headers = curl_slist_append(headers, requestHeaders.c_str());
}
// Set the size of the file to be uploaded.
if (!fileSize.empty()) {
curl_slist_append(headers, fileSize.c_str());
}
rc = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
} else {
// Set the size of the file to be uploaded.
if (!fileSize.empty()) {
rc = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_slist_append(NULL, fileSize.c_str()));
}
}

rc = curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
Expand All @@ -286,9 +333,14 @@ int NetworkLibrary::sendRequest(lua_State *L)

rc = curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);

// Set the callback function for response headers.
rc = curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, curlHeaderCallback);
rc = curl_easy_setopt(curl, CURLOPT_HEADERDATA, &requestParams->fResponseHeaders);

rc = curl_easy_setopt(curl, CURLOPT_WRITEDATA, &requestParams->fResponse);
rc = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlWriteData);
rc = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
rc = curl_easy_setopt(curl, CURLOPT_TIMEOUT, requestParams->getTimeout());

long status = 0;
smart_ptr<NetworkRequestState> requestState = new NetworkRequestState();
Expand Down Expand Up @@ -458,7 +510,7 @@ int NetworkLibrary::RemoveSystemEventListener(lua_State *L, int systemEventListe

// ----------------------------------------------------------------------------

} // namespace Corona
// }// namespace Corona

// ----------------------------------------------------------------------------

Expand Down
20 changes: 11 additions & 9 deletions platform/linux/src/NetworkLibrary.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//////////////////////////////////////////////////////////////////////////////
//
// This file is part of the Corona game engine.
// For overview and more information on licensing please refer to README.md
// For overview and more information on licensing please refer to README.md
// Home page: https://github.com/coronalabs/corona
// Contact: [email protected]
//
Expand All @@ -14,8 +14,10 @@

#include "Corona/CoronaLua.h"
#include "Corona/CoronaMacros.h"
#include "Rtt_Event.h"
#include "Rtt_LinuxContainer.h"
#include "NetworkSupport.h"
#include "Rtt_Scheduler.h"

namespace Rtt
{
Expand All @@ -29,7 +31,7 @@ namespace Rtt
fRequestState(requestState)
{
}

virtual ~NetworkCompletionEvent()
{
delete fRequestState;
Expand All @@ -38,7 +40,7 @@ namespace Rtt
static const char kName[];
virtual const char* Name() const { return kName; };
virtual int Push( lua_State *L ) const;

smart_ptr<NetworkRequestState> fRequestState;
};

Expand Down Expand Up @@ -79,20 +81,20 @@ namespace Rtt
class NetworkNotifierTask : public Task
{
public:

NetworkNotifierTask(NetworkRequestParameters* requestParams, NetworkRequestState* requestState, NetworkLibrary* lib)
: Task(true)
, fRequestParams(requestParams)
, fRequestState(requestState)
, fRequestParams(requestParams)
, fRequestState(requestState)
, fNetworkLibrary(lib)
{
}

virtual void operator()( Scheduler & sender );

smart_ptr<NetworkRequestParameters> fRequestParams;
smart_ptr<NetworkRequestState> fRequestState;
NetworkLibrary* fNetworkLibrary;
};

};
}
#endif // _NetworkLibrary_H__
6 changes: 6 additions & 0 deletions platform/linux/src/NetworkSupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,7 @@ NetworkRequestParameters::NetworkRequestParameters( lua_State *luaState)
fRequestBodySize = 0;
fResponseFile = NULL;
fLuaCallback = NULL;
fFileHandle = NULL;
fCURL = NULL;
fMultiCURL = NULL;

Expand Down Expand Up @@ -1022,9 +1023,14 @@ void NetworkRequestParameters::cancel()
curl_easy_cleanup(fCURL);
curl_multi_cleanup(fMultiCURL);

if (fFileHandle != NULL) {
fclose(fFileHandle);
}

// to prevent multiple calls
fMultiCURL = NULL;
fCURL = NULL;
fFileHandle = NULL;
}
}

Expand Down
4 changes: 4 additions & 0 deletions platform/linux/src/NetworkSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,13 +228,16 @@ class NetworkRequestParameters: public ref_counted
bool isDebug();
bool getHandleRedirects();
lua_State* getLuaState() const { return fL; };
FILE* getFileHandle() const { return fFileHandle; };
CURL* getCURL() const { return fCURL; };
CURLM* getMultiCURL() const { return fMultiCURL; };
void setCURL(CURLM* curlMulti, CURL* curl) { fCURL = curl; fMultiCURL = curlMulti; };
void setFileHandle(FILE* handle) { fFileHandle = handle; };
unsigned int getID() const { return fID; }
void cancel();

membuf fResponse;
UTF8String fResponseHeaders;

private:

Expand All @@ -253,6 +256,7 @@ class NetworkRequestParameters: public ref_counted
bool fIsValid;
bool fHandleRedirects;
lua_State* fL;
FILE* fFileHandle;
CURL* fCURL;
CURLM* fMultiCURL;
unsigned int fID;
Expand Down

0 comments on commit 0d676ea

Please sign in to comment.