@@ -263,6 +263,9 @@ public async Task ConnectAsync(ConnectionSettings cs, ILoadBalancer loadBalancer
263
263
264
264
if ( m_useCompression )
265
265
m_payloadHandler = new CompressedPayloadHandler ( m_payloadHandler . ByteHandler ) ;
266
+
267
+ if ( ShouldGetRealServerDetails ( ) )
268
+ await GetRealServerDetailsAsync ( ioBehavior , CancellationToken . None ) . ConfigureAwait ( false ) ;
266
269
}
267
270
catch ( IOException ex )
268
271
{
@@ -810,6 +813,65 @@ bool ValidateRemoteCertificate(object rcbSender, X509Certificate rcbCertificate,
810
813
}
811
814
}
812
815
816
+ // Some servers are exposed through a proxy, which handles the initial handshake and gives the proxy's
817
+ // server version and thread ID. Detect this situation and return `true` if the real server's details should
818
+ // be requested after connecting (which takes an extra roundtrip).
819
+ private bool ShouldGetRealServerDetails ( )
820
+ {
821
+ // currently hardcoded to the version returned by the Azure Database for MySQL proxy
822
+ return ServerVersion . OriginalString == "5.6.26.0" ;
823
+ }
824
+
825
+ private async Task GetRealServerDetailsAsync ( IOBehavior ioBehavior , CancellationToken cancellationToken )
826
+ {
827
+ try
828
+ {
829
+ await SendAsync ( QueryPayload . Create ( "SELECT CONNECTION_ID(), VERSION();" ) , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
830
+
831
+ // column count: 2
832
+ await ReceiveReplyAsync ( ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
833
+
834
+ // CONNECTION_ID() and VERSION() columns
835
+ await ReceiveReplyAsync ( ioBehavior , CancellationToken . None ) . ConfigureAwait ( false ) ;
836
+ await ReceiveReplyAsync ( ioBehavior , CancellationToken . None ) . ConfigureAwait ( false ) ;
837
+
838
+ PayloadData payload ;
839
+ if ( ! SupportsDeprecateEof )
840
+ {
841
+ payload = await ReceiveReplyAsync ( ioBehavior , CancellationToken . None ) . ConfigureAwait ( false ) ;
842
+ EofPayload . Create ( payload ) ;
843
+ }
844
+
845
+ // first (and only) row
846
+ int ? connectionId = default ;
847
+ string serverVersion = null ;
848
+ payload = await ReceiveReplyAsync ( ioBehavior , CancellationToken . None ) . ConfigureAwait ( false ) ;
849
+ var reader = new ByteArrayReader ( payload . ArraySegment ) ;
850
+ var length = reader . ReadLengthEncodedIntegerOrNull ( ) ;
851
+ if ( length != - 1 )
852
+ connectionId = int . Parse ( Encoding . UTF8 . GetString ( reader . ReadByteString ( length ) ) , CultureInfo . InvariantCulture ) ;
853
+ length = reader . ReadLengthEncodedIntegerOrNull ( ) ;
854
+ if ( length != - 1 )
855
+ serverVersion = Encoding . UTF8 . GetString ( reader . ReadByteString ( length ) ) ;
856
+
857
+ // OK/EOF payload
858
+ payload = await ReceiveReplyAsync ( ioBehavior , CancellationToken . None ) . ConfigureAwait ( false ) ;
859
+ if ( OkPayload . IsOk ( payload , SupportsDeprecateEof ) )
860
+ OkPayload . Create ( payload , SupportsDeprecateEof ) ;
861
+ else
862
+ EofPayload . Create ( payload ) ;
863
+
864
+ if ( connectionId . HasValue && serverVersion != null )
865
+ {
866
+ ConnectionId = connectionId . Value ;
867
+ ServerVersion = new ServerVersion ( serverVersion ) ;
868
+ }
869
+ }
870
+ catch ( MySqlException )
871
+ {
872
+ }
873
+ }
874
+
813
875
private void ShutdownSocket ( )
814
876
{
815
877
Utility . Dispose ( ref m_payloadHandler ) ;
0 commit comments