I got a "Unable to read data from the transport connection" error with the follow codes,
but it works with the old version.
thank you.
var proxy = "http://192.168.1.200:8080";
var client = new DirectoryService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Gbackuper Directory Helper Class",
HttpClientFactory = new ProxyHttpClientFactory(proxy),
});
var orgunitsRequest = client.Orgunits.List("my_customer");
orgunitsRequest.Type = OrgunitsResource.ListRequest.TypeEnum.All;
var orgs = await orgunitsRequest.ExecuteAsync(cancellationToken);
public class ProxyHttpClientFactory : HttpClientFactory
{
private string _proxyUrl;
public ProxyHttpClientFactory(string proxyUrl)
{
_proxyUrl = proxyUrl;
}
protected override HttpMessageHandler CreateHandler(CreateHttpClientArgs args)
{
var proxy = new WebProxy(_proxyUrl, true) { UseDefaultCredentials = false };
return new HttpClientHandler { UseProxy = true, Proxy = proxy};
}
}
Could you specify exactly what you mean by "old version" and "new version"? Please provide a complete stack trace as well. Without more information it's going to be very hard to help you.
thanks for your prompt reply. here is the stack trace:
at Google.Apis.Http.ConfigurableMessageHandler.
d__68.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult() at System.Net.Http.HttpClient.<FinishSendAsyncBuffered>d__62.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Google.Apis.Auth.OAuth2.Requests.TokenRequestExtenstions.<ExecuteAsync>d__0.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Google.Apis.Auth.OAuth2.ServiceAccountCredential.<RequestAccessTokenAsync>d__23.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Google.Apis.Auth.OAuth2.TokenRefreshManager.<RefreshTokenAsync>d__12.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Google.Apis.Auth.OAuth2.TokenRefreshManager.ResultWithUnwrappedExceptions[T](Task1 task)
at System.Threading.Tasks.ContinuationResultTaskFromResultTask2.InnerInvoke() at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot) at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Google.Apis.Auth.OAuth2.TokenRefreshManager.<GetAccessTokenForRequestAsync>d__10.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Google.Apis.Auth.OAuth2.ServiceAccountCredential.<GetAccessTokenForRequestAsync>d__24.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Google.Apis.Auth.OAuth2.ServiceCredential.<InterceptAsync>d__26.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Google.Apis.Http.ConfigurableMessageHandler.<CredentialInterceptAsync>d__69.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Google.Apis.Http.ConfigurableMessageHandler.<SendAsync>d__68.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult()
at System.Net.Http.HttpClient.d__62.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Google.Apis.Requests.ClientServiceRequest1.<ExecuteUnparsedAsync>d__30.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Google.Apis.Requests.ClientServiceRequest1.Execute()
at GBackuper.Program.AdminInfo() in D:\Backuper\Program.cs:line 156
And the specific versions that did and didn't work?
Forgive me, the working version is a modified version for v1.40.2, my workmate released it.
I tried the V1.44.1 which downloaded from nuget packages, and it doesnot work with a proxy with the ProxyHttpClientFactory class.
So does the original 1.40.2 have the same problem? What about releases between those two? Without a proxy here to test against, it's going to be hard to pin down the problem, especially when the working version is a patched one containing code I don't know about.
the problem is the GoogleCredential class cann't get token via a proxy?
here is the code I used:
GoogleCredential credential;
using (var stream = new FileStream(serviceAccountCredentialJsonFilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
credential = GoogleCredential.FromStream(stream)
.CreateScoped(new[] { DriveService.Scope.Drive })
.CreateWithUser(adminEmail);
}
if (!string.IsNullOrEmpty(_settings.Proxy)) //setup proxy here
{
var proxy = new WebProxy(_settings.Proxy, true);
var config = new HttpClientHandler
{
UseProxy = true,
Proxy = proxy
};
credential.UnderlyingCredential.Initialize(new ConfigurableHttpClient(new ConfigurableMessageHandler(config)));
}
It's not clear where that code in, to be honest. Is that code within your patched version of 1.40.2? Or is it in your application code, and is effectively part of the code in the first comment here?
The whole situation is very confusing at the moment. What I could really do with is:
Without those three pieces of information, I don't think we're going to be able to help you.
Please just disregard the "vanilla" version, since I don't have the source code :(
So have you tried your code against older versions of the library? It would be really, really helpful to know whether this is something that's been broken, or whether it's never worked.
Your zip file contains a service account JSON file. As this is now public, I strongly advise you to delete that service account from your GCP project, as otherwise anyone seeing this issue could use it.
Please try this code, which I'd expect to work - basically you need your credential to know the client factory to use:
var scopes = new[]
{
DirectoryService.Scope.AdminDirectoryDomainReadonly,
DirectoryService.Scope.AdminDirectoryOrgunitReadonly,
DirectoryService.Scope.AdminDirectoryUserReadonly,
DirectoryService.Scope.AdminDirectoryDomainReadonly
};
var serviceCredentialFromFile = (ServiceAccountCredential) GoogleCredential.FromFile(sa_file).UnderlyingCredential;
// Specify the scopes, proxy and impersonation in the new initializer, all in one go, just for simplicity.
var initializer = new ServiceAccountCredential.Initializer(serviceCredentialFromFile.Id)
{
ProjectId = serviceCredentialFromFile.ProjectId,
Key = serviceCredentialFromFile.Key,
User = user_email,
HttpClientFactory = new ProxyHttpClientFactory(proxy),
Scopes = scopes
};
var credential = GoogleCredential.FromServiceAccountCredential(new ServiceAccountCredential(initializer));
Please try this code, which I'd expect to work - basically you need your credential to know the client factory to use:
var scopes = new[] { DirectoryService.Scope.AdminDirectoryDomainReadonly, DirectoryService.Scope.AdminDirectoryOrgunitReadonly, DirectoryService.Scope.AdminDirectoryUserReadonly, DirectoryService.Scope.AdminDirectoryDomainReadonly }; var serviceCredentialFromFile = (ServiceAccountCredential) GoogleCredential.FromFile(sa_file).UnderlyingCredential; // Specify the scopes, proxy and impersonation in the new initializer, all in one go, just for simplicity. var initializer = new ServiceAccountCredential.Initializer(serviceCredentialFromFile.Id) { ProjectId = serviceCredentialFromFile.ProjectId, Key = serviceCredentialFromFile.Key, User = user_email, HttpClientFactory = new ProxyHttpClientFactory(proxy), Scopes = scopes }; var credential = GoogleCredential.FromServiceAccountCredential(new ServiceAccountCredential(initializer));
awesome, it works!!!
Okay, great. Will close this issue.
Most helpful comment
awesome, it works!!!