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

Feature request: HttpClient should accept existing Socket objects to establish the connection #43277

Closed
zichangg opened this issue Sep 1, 2020 · 7 comments
Assignees
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-_http type-enhancement A request for a change that isn't a bug

Comments

@zichangg
Copy link
Contributor

zichangg commented Sep 1, 2020

HttpClient is not able to reuse existing sockets. It will always use _SecureSocket or _Socket (dart:io implementation of SecureSocket/Socket). Self-written Sockets are not allowed. Users will have to use IOOverride as a workaround.

With this feature, it grants the freedom to users to choose the underlying connection. e.g. Unix domain sockets, which was supported a while ago, can be easily installed to HttpClient.

It also potential boosts the performance if used properly.

@zichangg zichangg added area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. type-enhancement A request for a change that isn't a bug library-_http labels Sep 1, 2020
@hacker1024
Copy link
Contributor

IOOverride does not even allow overriding SecureSocket.startConnect or SecureSocket.connect, so there's no workaround at all to use a custom socket with HTTPS.

@inst-cicada
Copy link

@zichangg can you please elaborate the problem? The one I am getting is that if you are unable to use existing sockets for eg. you are getting error wile connecting with locally hosted API and getting Socket Exception Error. Then to fix those issue follow the steps given below:

  1. Open Android Studio and open your Flutter Project.
  2. Start your Android Emulator.
  3. Start your API in local server and note the host url along with port. e.g. http://xxx.xxx.xx.x:5000
  4. After hosting the API open Command Line and run the following code:
    adb reverse tcp:<hosting port here> tcp:<hosting port here>
    eg. suppose you have hosted your api in http://xxx.xxx.xx.x:5000 then put 5000 in and use
    http://xxx.xxx.xx.x:5000 in HttpClient to get or post.
  5. Go to your dart file and run the code.

It worked for me.
Sorry If I got your problem wrong. I'm new to developing so.
And if I got it right. Cheers.

@brianquinlan
Copy link
Contributor

I have a design proposal to tackle this issue. Any feedback would be welcome:
https://docs.google.com/document/d/1W8TsGXQheNrxQSulr1S3BscZ_ncUsXuPhpAlTsp6lsU/edit#heading=h.xgjl2srtytjt

@brianquinlan
Copy link
Contributor

I'm going to mark this as fixed by a0aeed9 - if that is not sufficient, please reopen.

@hacker1024
Copy link
Contributor

hacker1024 commented Feb 11, 2022

@brianquinlan

I'm trying to use the solution added on a0aeed9 to use a SSL HTTP(S) proxy.

I have built SDK revision 9863451 with d6a4eda reverted.

final client = IOClient(HttpClient()
  ..findProxy = ((_) => 'PROXY username:password@au755.nordvpn.com:89')
  ..connectionFactory = ((url, proxyHost, proxyPort) {
    // I'm assuming a SSL proxy is provided here for the sake of simplicity.
    return SecureSocket.startConnect(proxyHost!, proxyPort!);
  }));
await client.read(Uri.parse('https://dart.dev'))

This fails with the following error:

Unhandled exception:
NoSuchMethodError: Class '_RawSocket' has no instance getter 'closedReadEventSent'.
Receiver: Instance of '_RawSocket'
Tried calling: closedReadEventSent
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:38:5)
#1      new _RawSecureSocket (dart:io/secure_socket.dart:527:21)
#2      _RawSecureSocket.connect (dart:io/secure_socket.dart:469:16)
#3      RawSecureSocket.secure (dart:io/secure_socket.dart:289:29)
#4      SecureSocket.secure.<anonymous closure> (dart:io/secure_socket.dart:110:30)
<asynchronous suspension>
#5      _HttpClient._openUrl.<anonymous closure> (dart:_http/http_impl.dart:2721:15)
<asynchronous suspension>

The error happens after the authentication stage; if the credentials are wrong, I receive an HTTP 407 error from the proxy server.

It's also worth noting that replacing https://dart.dev with a plaintext HTTP website works just fine.

@brianquinlan
Copy link
Contributor

Hi @hacker1024 - if you change the code to not use connectionFactory does this work? ie

final client = IOClient(HttpClient()
  ..findProxy = ((_) => 'PROXY username:password@au755.nordvpn.com:89');
await client.read(Uri.parse('https://dart.dev'))

If so, could you file another bug to track this issue?

@hacker1024
Copy link
Contributor

@brianquinlan It does not. See: #43876.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-_http type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

4 participants