Skip to content

Conversation

@grendello
Copy link
Contributor

The changes are result of a
bug (https://bugzilla.xamarin.com/show_bug.cgi?id=55477) followup and are based
on code and ideas from Jeremy Cook [email protected]:

  • If UseProxy == false instantiate Java URLConnection that doesn't use the
    system proxy. This is important for code that accesses local resources from a
    device otherwise configured to use a proxy.

  • Allow for insecure SSL requests: let the code bypass SSL host name and
    certificate checks. This is necessary for code that connects to devices with
    self-signed or otherwise "invalid" SSL certificates as well as ones which do
    not have valid DNS entries set up for them.
    The implementation makes it possible to use a custom host name verifier and
    also to provide a custom socket factory.

The changes are result of a
bug (https://bugzilla.xamarin.com/show_bug.cgi?id=55477) followup and are based
on code and ideas from Jeremy Cook <[email protected]>:

 * If `UseProxy == false` instantiate Java URLConnection that doesn't use the
   system proxy. This is important for code that accesses local resources from a
   device otherwise configured to use a proxy.

 * Allow for insecure SSL requests: let the code bypass SSL host name and
   certificate checks. This is necessary for code that connects to devices with
   self-signed or otherwise "invalid" SSL certificates as well as ones which do
   not have valid DNS entries set up for them.
	 The implementation makes it possible to use a custom host name verifier and
   also to provide a custom socket factory.
/// </summary>
/// <returns>Instance of SSLSocketFactory ready to use with the HTTPS connection.</returns>
/// <param name="connection">HTTPS connection to return socket factory for</param>
protected virtual SSLSocketFactory ConfigureCustomSSLSocketFactory (HttpsURLConnection connection)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this instead be called CreateCustomSslSocketFactory()? Configure, to me, implies that it's configuring an existing instance/state, not creating and returning new state. (Based on return type, I'm assuming it can't be configuring existing state.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's more than just creation though, see the code below in SetupSSL - I debated calling it Create* but thought that it doesn't reflect the full spectrum

if (httpsConnection != null) {
IHostnameVerifier hnv = GetSSLHostnameVerifier (httpsConnection);
if (hnv != null)
httpsConnection.HostnameVerifier = hnv;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need to make property assignment conditional? I'd think that this should be fine:

httpsConnection.HostnameVerifier = GetSSLHostnameVerifier (httpsConnection);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want to change the default property value if the method returns null

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, there's a default property value that isn't null...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More that it's a property with unknown default value and we don't want to disturb the default state unless we're 100% sure what the effect would be

/// <paramref name="connection"/>
/// </summary>
/// <returns>Instance of IHostnameVerifier to be used for this HTTPS connection</returns>
/// <param name="connection">HTTPS connection object.</param>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naming conventions: Should this really be SSL or should it be Ssl?

I'm also not sure if it should be Hostname or HostName, though given that the (pre-existing?) type is IHostnameVerifier, Hostname should probably be preferred.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hostname is taken from the interface name (and I don't like it, but - consistency). And I don't like camel-casing TLAs...

@jonpryor
Copy link
Contributor

This PR should contain tests for the new members, e.g. to demonstrate how they're intended to be use (and verify that they actually work for that purpose).

@grendello
Copy link
Contributor Author

Tests require setting up a few test URLs with different SSL certificates. I'd suggest we merge the PR and I'll work on the tests at a later time - the code might be useful for a few people out there :)

@jonpryor jonpryor merged commit 8354bef into dotnet:master May 30, 2017
@grendello grendello deleted the httpclient-assorted-changes branch May 31, 2017 20:39
jonpryor pushed a commit to jonpryor/xamarin-android that referenced this pull request Jun 5, 2017
…#612)

The changes are result of a
bug (https://bugzilla.xamarin.com/show_bug.cgi?id=55477) followup and are based
on code and ideas from Jeremy Cook <[email protected]>:

 * If `UseProxy == false` instantiate Java URLConnection that doesn't use the
   system proxy. This is important for code that accesses local resources from a
   device otherwise configured to use a proxy.

 * Allow for insecure SSL requests: let the code bypass SSL host name and
   certificate checks. This is necessary for code that connects to devices with
   self-signed or otherwise "invalid" SSL certificates as well as ones which do
   not have valid DNS entries set up for them.
	 The implementation makes it possible to use a custom host name verifier and
   also to provide a custom socket factory.
jonpryor pushed a commit that referenced this pull request Jun 6, 2017
The changes are result of a
bug (https://bugzilla.xamarin.com/show_bug.cgi?id=55477) followup and are based
on code and ideas from Jeremy Cook <[email protected]>:

 * If `UseProxy == false` instantiate Java URLConnection that doesn't use the
   system proxy. This is important for code that accesses local resources from a
   device otherwise configured to use a proxy.

 * Allow for insecure SSL requests: let the code bypass SSL host name and
   certificate checks. This is necessary for code that connects to devices with
   self-signed or otherwise "invalid" SSL certificates as well as ones which do
   not have valid DNS entries set up for them.
	 The implementation makes it possible to use a custom host name verifier and
   also to provide a custom socket factory.
jonpryor added a commit to jonpryor/xamarin-android that referenced this pull request Mar 27, 2020
Changes: dotnet/java-interop@1a086ff...56c92c7

  * dotnet/java-interop@56c92c7: [build] Remove cecil submodule (dotnet#597)
  * dotnet/java-interop@3091274: [build] Provide a default $(Configuration) value (dotnet#612)
  * dotnet/java-interop@cf3e7c2: [generator] Don't process duplicate reference assemblies (dotnet#611)
  * dotnet/java-interop@f5fa462: [jnienv-gen] Convert to SDK-style (dotnet#608)
jonpryor added a commit that referenced this pull request Mar 27, 2020
Changes: dotnet/java-interop@1a086ff...56c92c7

  * dotnet/java-interop@56c92c7: [build] Remove cecil submodule (#597)
  * dotnet/java-interop@3091274: [build] Provide a default $(Configuration) value (#612)
  * dotnet/java-interop@cf3e7c2: [generator] Don't process duplicate reference assemblies (#611)
  * dotnet/java-interop@f5fa462: [jnienv-gen] Convert to SDK-style (#608)

Of particular note is [dotnet/java-interop@56c92c7][0], which
replaces the `mono/cecil` submodule within Java.Interop with the
[`Mono.Cecil` NuGet package][1] in an effort to simplify the
Java.Interop build system.

This simplifies the Java.Interop repo, and we *thought* that since
xamarin-android *doesn't even use* Java.Interop's cecil submodule-built
`Mono.Cecil.dll` -- instead the `Mono.Cecil.dll` from the
"mono archive" is "renamed" to `Xamarin.Android.Cecil.dll` during
`make prepare` (0c9f83b) -- surely this would be a simple change.

The removal of the cecil submodule also required changing
`ThirdPartyNotice.txt` generation so that the LICENSE for Cecil was
obtained from the mono archive instead of from Java.Interop.

Unfortunately, the integration was a tad more complicated than
anticipated.  With the ongoing adoption of MSBuild multi-targeting
and builds against the `netcoreapp3.1` target framework -- commit
e2854ee and numerous commits in Java.Interop -- we encountered a
problem with MSBuild semantics: If two `$(TargetFramework)` builds
share the same output directory, the `IncrementalClean` target will
*remove files created by previous builds*, e.g. when e.g.
`Java.Interop/tools/generator.csproj` builds the `netcoreapp3.1`
framework, it will *delete* the `generator.exe` built by the `net472`
framework, which results in subsequent build breaks.

The only path to sanity is to *ensure* that different
`$(TargetFramework)` builds have *completely separate* `$(OutputPath)`
values.  The "normal" approach to doing this is for `$(OutputPath)`
to end with `$(TargetFramework)`, which is the case when
`$(AppendTargetFrameworkToOutputPath)`=True (the default).

Unfortunately in xamarin-android we don't want `$(OutputPath)` to end
with `$(TargetFramework)`; we want the build tree structure to mirror
the installation directory structure, which -- at present -- doesn't
mention `$(TargetFramework)` at all.

The solution here is to use "non-overlapping" directories.  For
example, in e2854ee there are "two" `$(OutputPath)` values:

  * `MonoAndroid10.0`: `bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v10.0/Mono.Android.dll`
  *   `netcoreapp3.1`: `bin/Debug/lib/xamarin.android/xbuild-frameworks/Xamarin.Android.App/netcoreapp3.1/Mono.Android.dll`

The same "non-overlapping directories" strategy needs to be extended
to *all* multi-targeted projects from Java.Interop, *including*
dependencies.  Dependencies such as `Xamarin.Android.Cecil.dll`.

Define a new `$(UtilityOutputFullPathCoreApps)` MSBuild property so
that Java.Interop "utility" project builds, when building for the
`netcoreapp3.1` framework, use a *different* `Xamarin.Android.Cecil.dll`
than is used with the `net472`-related builds.

Update `xaprepare` to *create* this new `netcoreapp3.1`-correlated
`Xamarin.Android.Cecil.dll`.  It's the same file, just in a different
directory, to prevent "accidental" deletes by `IncrementalClean`.

Even with all that, MSBuild still had other ideas.  In particular,
MSBuild wasn't particularly happy about our attempt to use the
`$(UtilityOutputFullPath)` property to "switch" between using a
`@(PackageReference)` to the Mono.Cecil NuGet package vs. using a
`@(Reference)` to the `Xamarin.Android.Cecil.dll` assembly, because
MSBuild *caches* this information somewhere within `obj` directories.

To get MSBuild to re-evaluate it's assembly reference choices, we must
instead replace `msbuild` with `msbuild /restore`.

Which still isn't enough, because some of our MSBuild invocations are
via the `<MSBuild/>` task, within `msbuild`.  To get *that* working,
we need to explicitly invoke the `Restore` target through a *separate*
`<MSBuild/>` task invocation.  You ***CANNOT*** use
`<MSBuild Targets="Restore;Build" />`, as "obvious" as that may be,
because it [doesn't work reliably][2].  ([Yet.][3])

[0]: dotnet/java-interop@56c92c7
[1]: https://www.nuget.org/packages/Mono.Cecil/0.11.2
[2]: dotnet/msbuild#3000 (comment)
[3]: dotnet/msbuild#2811
@github-actions github-actions bot locked and limited conversation to collaborators Feb 2, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants