Skip to content
New issue

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

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

Already on GitHub? # to your account

All calls to megaclient API hanging #178

Closed
itzlokeshjayaraj opened this issue Sep 22, 2021 · 21 comments · Fixed by #186
Closed

All calls to megaclient API hanging #178

itzlokeshjayaraj opened this issue Sep 22, 2021 · 21 comments · Fixed by #186
Assignees
Labels
Milestone

Comments

@itzlokeshjayaraj
Copy link

Description: I logged in using "sessionid" and "masterkey".

what are you trying to do
Trying to fetch account info, get nodes, download link, etc.

Actual Behavior:
The methods GetAccountInformation(...) , GetNodes(...), etc,., is hanging for ever.
what happens
Any call to these methods are hanging..

Expected Behavior:
The methods GetAccountInformation(...) , GetNodes(...) should return appropriate objects on success.
what should happen
These methods were working fine previously, but all of sudden not working now

Steps to Reproduce:

  1. Login using "sessionid" and "masterkey".
  2. Call GetAccountInformation(...) or GetNodes(...) or any other method
  3. No response but instead hanging
  4. Sometimes i am getting these errors but not consistent
    " at CG.Web.MegaApiClient.MegaApiClient.RequestCore[TResponse](RequestBase request, Byte[] key)\r\n at CG.Web.MegaApiClient.MegaApiClient.Request[TResponse](RequestBase request, Byte[] key)\r\n at CG.Web.MegaApiClient.MegaApiClient.GetAccountInformation()\r\n at

OR

" at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)\r\n at System.Threading.Tasks.Task1.GetResultCore(Boolean waitCompletionNotification)\r\n at System.Threading.Tasks.Task1.get_Result()\r\n at CG.Web.MegaApiClient.WebClient.PostRequest(Uri url, Stream dataStream, String contentType)\r\n at CG.Web.MegaApiClient.WebClient.PostRequestJson(Uri url, String jsonData)\r\n at CG.Web.MegaApiClient.MegaApiClient.RequestCore[TResponse](RequestBase request, Byte[] key)\r\n at CG.Web.MegaApiClient.MegaApiClient.Request[TResponse](RequestBase request, Byte[] key)\r\n at CG.Web.MegaApiClient.MegaApiClient.GetAccountInformation()\r\n

MegaApiClient Version: 1,7 to 1.9

@gpailler
Copy link
Owner

I tried to reproduce your issue but everything is working properly. Maybe it's a network issue on your side. Did you check with another account and/or another PC?

@itzlokeshjayaraj
Copy link
Author

Hi,
The issue is not consistent. It is working for some accounts(same or different PC) whereas not so for some others.
Also For the same account, but with different session id's, one is working and other not so.
The accounts which are working too takes a lot of time to respond.(~ 2mins).
Sometimes Manual proxy setup is "enabled" to use proxy server and issue appears at that time, but that too not consistent. So, it is difficult for me to correlate the exact reason.
Any clues to sort out the issue is appreciated...
Thanks in advance...

@gpailler
Copy link
Owner

You can subscribe the event IMegaApiClient.ApiRequestFailed to get some details about the API failures.
From my experience, Mega has some rate-limiting policy that could lead to the behavior you are describing.
Do you use free or pro accounts?

@itzlokeshjayaraj
Copy link
Author

Hi,
Can you share a code snippet of how to subscribe this event IMegaApiClient.ApiRequestFailed.?
FYI, Mine is a free account and Can you share some doc/articles to know more on this rate-limiting policy?

@gpailler
Copy link
Owner

For example:

var client = new MegaApiClient();
client.ApiRequestFailed += OnApiRequestFailed;

[...]

private void OnApiRequestFailed(object _, ApiRequestFailedEventArgs e)
{
  Debug.WriteLine($"ApiRequestFailed: {e.ApiResult}, {e.ApiUrl}, {e.AttemptNum}, {e.RetryDelay}, {e.ResponseJson}, {e.Exception} {e.Exception?.Message}");
}

About the rate limit, it's mentioned on the Mega doc => https://mega.nz/doc (API_ERATELIMIT) but there is not much details.
Anyway, the snippet I posted above could help to understand the root issue.

@itzlokeshjayaraj
Copy link
Author

Hi, Implemented the subscription as per your code snippet. The methods GetAccountInformation(...) , GetNodes(...), etc,., is hanging for ever or giving responses after ~ 2 mins. But control is never coming to the OnApiRequestFailed(....) method
FYI, sometimes Manual proxy setup is turned on while hanging, but it is not consistent.

@gpailler
Copy link
Owner

gpailler commented Oct 2, 2021

Well, then there is no throttling if OnApiRequestFailed is never called.
You can use Fiddler or implement your own IWebClient to investigate the connections and try to understand why it's taking so long.

@gpailler
Copy link
Owner

gpailler commented Oct 9, 2021

@itzlokeshjayaraj Could you try the solution posted on #181 (comment). It looks it's exactly the issue you are facing.

@Tonnilson
Copy link

Tonnilson commented Oct 11, 2021

I have also experienced issues with various things hanging, more specifically LoginAnonymousAsync();
I have suspected it to be an issue with rate limiting but even so if a client does hit a rate limit the task shouldn't be left hanging. So far I have not encountered any errors being thrown as it hangs for quite some time. Would be nice if we could set some form of a timeout introduced for various requests like login, retrieving nodes and downloading.

@Bluekey21
Copy link

We have an aplication in VB.NET where we use the API “MegaApiCliente” for uploading files, but since the last september 30, the app hasn’t work as usual, it means, isn’t uploading files to our account of Mega.

The code line is as follows:

Dim Cliente As New MegaApiClient()
Cliente.Login("micorreo.com", "mypassword")

The app it seems uploading files but there isn’t any messange error, our project was updated with the 1.9.0.0 API’s versión. So, one question, do we have to send any extra to our API?.

Please we will wait for your support, could you please send us any documentation?

@gpailler
Copy link
Owner

Documentation is updated with a note about new TLS requirement

⚠️ TLS 1.2 support should be configured explicitely when using .NET Framework <= 4.5 or all the API calls to Mega will hang.

  • For .NET Framework 4.5, add ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
  • For .NET Framework 4, add ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; (.NET 4.5 should be installed on the machine).

⚠️ TLS 1.2 support should be configured explicitely when using .NET Framework <= 4.5 or all the API calls to Mega will hang.
- For .NET Framework 4.5, add `ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;`
- For .NET Framework 4, add `ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;` (.NET 4.5 should be installed on the machine).

@mastercho
Copy link

mastercho commented Oct 20, 2021

using .NET Core 5 with your lib and supports TLS 1.2 and issue still exists and is exactly as itzlokeshjayaraj describes hungs on some and works for some other. I just test with normal HTTP req to mega API and its working fine but with normal HTTP is flagged as suspicious activity and would lock your account. Was good library until this issue is come out, maybe they change something you have to look deeper into this issue.

Hi, The issue is not consistent. It is working for some accounts(same or different PC) whereas not so for some others. Also For the same account, but with different session id's, one is working and other not so. The accounts which are working too takes a lot of time to respond.(~ 2mins). Sometimes Manual proxy setup is "enabled" to use proxy server and issue appears at that time, but that too not consistent. So, it is difficult for me to correlate the exact reason. Any clues to sort out the issue is appreciated... Thanks in advance...

@itzlokeshjayaraj
Copy link
Author

Sorry for the delay in reply.
I am using .net framework 4.6.1 in Windows 10 Pro, Version 21H1, OS Build 19043.1288. It seems .net framework 4.6.1 supports Tls12 by default so there is no need for explicitly adding this security protocol.
FYI, I have also tried using the method megaApiClient.Login("xxxx@gmail.com", "yyyy") and it still hangs, Where as same credentials works well to login in browser.

@gpailler
Copy link
Owner

@itzlokeshjayaraj So when you check ServicePointManager.SecurityProtocol, it contains SecurityProtocolType.Tls12 ? I'm asking because the SecurityProtocol can be different depending of some registry keys

@itzlokeshjayaraj
Copy link
Author

I have two applications, one sample application and other the main workspace and both built in net framework 4.6.1.
In sample application, ServicePointManager.SecurityProtocol contains "Ssl3 | Tls " and it is hanging. When added explicitly "Tls12", hanging is not happening.
In main workspace, ServicePointManager.SecurityProtocol contains "Tls | Tls11 | Tls12 | Tls13" and it is hanging. When added explicitly "Tls12", hanging is not happening.
Do we have to explicitly add SecurityProtocol irrespective of the .net framework??

@gpailler
Copy link
Owner

The documentation is a bit unclear but I think that Tls12 should be explicitly added for .Net Framework < 4.7
https://docs.microsoft.com/en-us/dotnet/api/system.net.servicepointmanager.securityprotocol?view=net-5.0

I will add an extra check in MegaApiClient and throw an explicit exception if Tls12 is not specified.

@Bluekey21
Copy link

Public Function Sube_Archivo_Mega(ByVal Usuario As String, ByVal Contrasena As String, ByVal CarpetaNube As String, ByVal RutaArchivo As String) As Boolean
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
Try

        Dim Cliente As New MegaApiClient()

        Cliente.Login(correo@gmail.com, xxxxx)

        Dim Nodos = Cliente.GetNodes()
        Dim Root As INode
        Dim Carpeta As INode

        If CarpetaNube <> "" Then
            Dim ExisteCarpeta As Boolean = Cliente.GetNodes().Any(Function(n) n.Name = CarpetaNube)

            If ExisteCarpeta = True Then
                Carpeta = Nodos.[Single](Function(n) n.Name = CarpetaNube)
            Else
                Root = Nodos.[Single](Function(n) n.Type = NodeType.Root)

                Carpeta = Cliente.CreateFolder(CarpetaNube, Root)
            End If
        Else
            Carpeta = Nodos.[Single](Function(n) n.Type = NodeType.Root)
        End If

        Dim Archivo As INode = Cliente.UploadFile(RutaArchivo, Carpeta)

        Dim DownloadUrl As Uri = Cliente.GetDownloadLink(Archivo)

        UrlDescarga = DownloadUrl.ToString

        Cliente.Logout()

And it still hangs, Where as same credentials works well to login in browser.

@sabihismail
Copy link
Contributor

sabihismail commented Oct 30, 2021

I'm having the same issue, I've only been able to trace it to the private TResponse RequestCore<TResponse>(RequestBase request, byte[] key) function never returning and infinitely stalling on some occasions, I'll update if I can get more specific.

Edit: Narrowed it to stalling in the function call to PostRequest(Uri url, Stream dataStream, string contentType) within PostRequestJson within RequestCore<TResponse>(RequestBase request, byte[] key). Is it possible that there is a deadlock here for these async .Result calls?

Edit 2: So this appears to be because this.httpClient.SendAsync in PostRequest(Uri url, Stream dataStream, string contentType) never exits for some reason since the httpClient timeout is set to infinite. Not entirely sure if this is a good solution, I set responseTimeout = 20000 in the constructor and changed PostRequestJson to

public string PostRequestJson(Uri url, string jsonData)
{
    try
    {
        using (MemoryStream jsonStream = new MemoryStream(jsonData.ToBytes()))
        {
            using (var responseStream = this.PostRequest(url, jsonStream, "application/json"))
            {
                return this.StreamToString(responseStream);
            }
        }
    }
    catch
    {
        return null;
    }
}

so that it throws an exception after 20 seconds rather than stalling forever. This causes for it to retry the same request (there's retry logic in the calling function) and I seem to not be blocked anymore. Hope this helps!

@Tonnilson
Copy link

Tonnilson commented Nov 1, 2021

I'm having the same issue, I've only been able to trace it to the private TResponse RequestCore<TResponse>(RequestBase request, byte[] key) function never returning and infinitely stalling on some occasions, I'll update if I can get more specific.

Edit: Narrowed it to stalling in the function call to PostRequest(Uri url, Stream dataStream, string contentType) within PostRequestJson within RequestCore<TResponse>(RequestBase request, byte[] key). Is it possible that there is a deadlock here for these async .Result calls?

Edit 2: So this appears to be because this.httpClient.SendAsync in PostRequest(Uri url, Stream dataStream, string contentType) never exits for some reason since the httpClient timeout is set to infinite. Not entirely sure if this is a good solution, I set responseTimeout = 20000 in the constructor and changed PostRequestJson to

public string PostRequestJson(Uri url, string jsonData)
{
    try
    {
        using (MemoryStream jsonStream = new MemoryStream(jsonData.ToBytes()))
        {
            using (var responseStream = this.PostRequest(url, jsonStream, "application/json"))
            {
                return this.StreamToString(responseStream);
            }
        }
    }
    catch
    {
        return null;
    }
}

so that it throws an exception after 20 seconds rather than stalling forever. This causes for it to retry the same request (there's retry logic in the calling function) and I seem to not be blocked anymore. Hope this helps!

The timeout being set to infinite by default is most likely the issue people are experiencing. With that in mind you can set the timeout to your desired timeout, catch it and handle it from there on your own. I was under the impression a timeout was already set by default and I'm sure a lot experiencing this issue think the same way.

Example of setting a timeout and handling the failed request on your own:

MegaApiClient client = new MegaApiClient(new WebClient(20000));

try
{
    client.LoginAnonymous();
}
catch
{
    //handle it here
}

Your solution works fine to make it auto retry but these things are use case and user preference. Having the option to set a property for auto-retrying and changing the DefaultResponseTimeout from infinite to something reasonable should be an appropriate fix / implementation.

@gpailler gpailler added this to the vNext milestone Nov 5, 2021
@gpailler gpailler self-assigned this Nov 5, 2021
gpailler added a commit that referenced this issue Nov 5, 2021
…epending of the target:

- net40 : check that (SecurityProtocolType)3072 is specified
- net45 : check that SecurityProtocolType.Tls12 is specified
- net46 : check that SecurityProtocolType.Tls12 is specified
- net47 (target added) : check that SecurityProtocolType.Tls12 or SecurityProtocolType.UseDefault is specified
- net471 (target added) : force usage of Tls12 in HttpClient ctor
- netstandard1.3 : force usage of Tls12 in HttpClient ctor
- netstandard2.0 : force usage of Tls12 in HttpClient ctor
@gpailler
Copy link
Owner

gpailler commented Nov 5, 2021

For those who can reproduce the API hanging issue, could you try the following NuGet package to confirm that an exception is thrown about the lack of Tls12 support?
https://www.myget.org/feed/megaapiclient/package/nuget/MegaApiClient/1.10.0-pullrequest0186-0012

Thanks

@gpailler gpailler linked a pull request Nov 5, 2021 that will close this issue
gpailler added a commit that referenced this issue Nov 7, 2021
* #178 Fix API calls hangs by checking Tls12 support or enforce Tls12 depending of the target:
- net40 : check that (SecurityProtocolType)3072 is specified
- net45 : check that SecurityProtocolType.Tls12 is specified
- net46 : check that SecurityProtocolType.Tls12 is specified
- net47 (target added) : check that SecurityProtocolType.Tls12 or SecurityProtocolType.UseDefault is specified
- net471 (target added) : force usage of Tls12 in HttpClient ctor
- netstandard1.3 : force usage of Tls12 in HttpClient ctor
- netstandard2.0 : force usage of Tls12 in HttpClient ctor

* #178 Update documentation about Tls 1.2 requirements
@gpailler gpailler reopened this Nov 7, 2021
@gpailler gpailler added the bug label Nov 10, 2021
@gpailler
Copy link
Owner

1.10.0 released

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants