diff --git a/.gitmodules b/.gitmodules
index 5e19cd95..e69de29b 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +0,0 @@
-[submodule "HttpTwo"]
- path = HttpTwo
- url = git@github.com:Redth/HttpTwo.git
diff --git a/HttpTwo b/HttpTwo
deleted file mode 160000
index 7ba7b0e8..00000000
--- a/HttpTwo
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 7ba7b0e814d326b063f45e95376b264bfd288980
diff --git a/PushSharp.Amazon/AdmConfiguration.cs b/PushSharp.Amazon/AdmConfiguration.cs
index 529fbbc1..1c39572b 100644
--- a/PushSharp.Amazon/AdmConfiguration.cs
+++ b/PushSharp.Amazon/AdmConfiguration.cs
@@ -1,6 +1,4 @@
-using System;
-
-namespace PushSharp.Amazon
+namespace PushSharp.Amazon
{
public class AdmConfiguration
{
diff --git a/PushSharp.Amazon/AdmConnection.cs b/PushSharp.Amazon/AdmConnection.cs
index 3ce9d346..00c9de5a 100644
--- a/PushSharp.Amazon/AdmConnection.cs
+++ b/PushSharp.Amazon/AdmConnection.cs
@@ -1,14 +1,11 @@
using System;
-using System.Threading.Tasks;
+using System.Collections.Generic;
+using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
+using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
-using System.Net;
-using PushSharp.Core;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.Serialization;
-using System.Threading;
+using PushSharp.Common;
namespace PushSharp.Amazon
{
diff --git a/PushSharp.Amazon/AdmNotification.cs b/PushSharp.Amazon/AdmNotification.cs
index 74dad5b4..1b6c64e6 100644
--- a/PushSharp.Amazon/AdmNotification.cs
+++ b/PushSharp.Amazon/AdmNotification.cs
@@ -1,7 +1,6 @@
-using System;
-using System.Collections.Generic;
-using PushSharp.Core;
+using System.Collections.Generic;
using Newtonsoft.Json.Linq;
+using PushSharp.Common;
namespace PushSharp.Amazon
{
diff --git a/PushSharp.Amazon/Exceptions.cs b/PushSharp.Amazon/Exceptions.cs
index b3f145b9..a0aea291 100644
--- a/PushSharp.Amazon/Exceptions.cs
+++ b/PushSharp.Amazon/Exceptions.cs
@@ -1,5 +1,4 @@
-using System;
-using PushSharp.Core;
+using PushSharp.Common;
namespace PushSharp.Amazon
{
diff --git a/PushSharp.Amazon/Properties/AssemblyInfo.cs b/PushSharp.Amazon/Properties/AssemblyInfo.cs
deleted file mode 100644
index a2f8a614..00000000
--- a/PushSharp.Amazon/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
-
-[assembly: AssemblyTitle ("PushSharp.Amazon")]
-[assembly: AssemblyDescription ("")]
-[assembly: AssemblyConfiguration ("")]
-[assembly: AssemblyCompany ("")]
-[assembly: AssemblyProduct ("")]
-[assembly: AssemblyCopyright ("redth")]
-[assembly: AssemblyTrademark ("")]
-[assembly: AssemblyCulture ("")]
-
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
-
-[assembly: AssemblyVersion ("1.0.*")]
-
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
-
diff --git a/PushSharp.Amazon/PushSharp.Amazon.csproj b/PushSharp.Amazon/PushSharp.Amazon.csproj
index 594d22c3..65fce3bc 100644
--- a/PushSharp.Amazon/PushSharp.Amazon.csproj
+++ b/PushSharp.Amazon/PushSharp.Amazon.csproj
@@ -1,56 +1,21 @@
-
-
+
+
- Debug
- AnyCPU
- {2468C63B-C964-4FC3-9B16-13DC17CF7D11}
- Library
- PushSharp.Amazon
+ netstandard2.0;net45;
PushSharp.Amazon
- v4.5
- true
- ..\PushSharp-Signing.snk
-
-
- true
- full
- false
- bin\Debug
- DEBUG;
- prompt
- 4
- false
-
-
- full
- true
- bin\Release
- prompt
- 4
- false
+ PushSharp.Amazon
+
-
-
-
- ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll
-
+
-
-
-
-
-
-
-
-
-
-
- {2B44A8DA-60BC-4577-A2D7-D9D53F164B2E}
- PushSharp.Core
-
+
+
+
+
-
+
-
\ No newline at end of file
+
+
diff --git a/PushSharp.Amazon/packages.config b/PushSharp.Amazon/packages.config
deleted file mode 100644
index 505e5883..00000000
--- a/PushSharp.Amazon/packages.config
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/PushSharp.Apple/ApnsConfiguration.cs b/PushSharp.Apple/ApnsConfiguration.cs
index 464a5e62..6a16a870 100644
--- a/PushSharp.Apple/ApnsConfiguration.cs
+++ b/PushSharp.Apple/ApnsConfiguration.cs
@@ -1,5 +1,6 @@
-using System;
+using System;
using System.Collections.Generic;
+using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text.RegularExpressions;
@@ -82,7 +83,7 @@ void Initialize (ApnsServerEnvironment serverEnvironment, X509Certificate2 certi
FeedbackIntervalMinutes = 10;
FeedbackTimeIsUTC = false;
-
+
AdditionalCertificates = new List ();
AddLocalAndMachineCertificateStores = false;
@@ -100,7 +101,6 @@ void Initialize (ApnsServerEnvironment serverEnvironment, X509Certificate2 certi
InternalBatchFailureRetryCount = 1;
}
-
void CheckIsApnsCertificate ()
{
if (Certificate != null) {
@@ -136,6 +136,22 @@ public void OverrideFeedbackServer (string host, int port)
FeedbackPort = port;
}
+ public void SetProxy(string proxyHost, int proxyPort)
+ {
+ UseProxy = true;
+ ProxyHost = proxyHost;
+ ProxyPort = proxyPort;
+ ProxyCredentials = CredentialCache.DefaultNetworkCredentials;
+ }
+
+ public void SetProxy(string proxyHost, int proxyPort, string userName, string password, string domain)
+ {
+ UseProxy = true;
+ ProxyHost = proxyHost;
+ ProxyPort = proxyPort;
+ ProxyCredentials = new NetworkCredential(userName, password, domain);
+ }
+
public string Host { get; private set; }
public int Port { get; private set; }
@@ -144,6 +160,14 @@ public void OverrideFeedbackServer (string host, int port)
public int FeedbackPort { get; private set; }
+ public bool UseProxy { get; private set; }
+
+ public string ProxyHost { get; private set; }
+
+ public int ProxyPort { get; private set; }
+
+ public NetworkCredential ProxyCredentials { get; private set; }
+
public X509Certificate2 Certificate { get; private set; }
public List AdditionalCertificates { get; private set; }
@@ -205,4 +229,4 @@ public enum ApnsServerEnvironment {
Production
}
}
-}
\ No newline at end of file
+}
diff --git a/PushSharp.Apple/ApnsConnection.cs b/PushSharp.Apple/ApnsConnection.cs
index 0908b166..3d65c18f 100644
--- a/PushSharp.Apple/ApnsConnection.cs
+++ b/PushSharp.Apple/ApnsConnection.cs
@@ -7,7 +7,11 @@
using System.Collections.Generic;
using System.Threading;
using System.Net;
-using PushSharp.Core;
+using System.Reflection;
+using System.Security.Cryptography;
+using System.Text;
+using PushSharp.Common;
+using System.Diagnostics;
namespace PushSharp.Apple
{
@@ -68,7 +72,6 @@ public ApnsConnection (ApnsConfiguration configuration)
byte[] buffer = new byte[6];
int id;
-
SemaphoreSlim connectingSemaphore = new SemaphoreSlim (1);
SemaphoreSlim batchSendSemaphore = new SemaphoreSlim (1);
object notificationBatchQueueLock = new object ();
@@ -127,28 +130,37 @@ async Task SendBatch ()
Log.Info ("APNS-Client[{0}]: Sending Batch ID={1}, Count={2}", id, batchId, toSend.Count);
- try {
+ try
+ {
var data = createBatch (toSend);
- if (data != null && data.Length > 0) {
+ if (data != null && data.Length > 0)
+ {
- for (var i = 0; i <= Configuration.InternalBatchFailureRetryCount; i++) {
+ for (var i = 0; i <= Configuration.InternalBatchFailureRetryCount; i++)
+ {
await connectingSemaphore.WaitAsync ();
- try {
+ try
+ {
// See if we need to connect
if (!socketCanWrite () || i > 0)
await connect ();
- } finally {
+ }
+ finally
+ {
connectingSemaphore.Release ();
}
- try {
+ try
+ {
await networkStream.WriteAsync(data, 0, data.Length).ConfigureAwait(false);
break;
- } catch (Exception ex) when (i != Configuration.InternalBatchFailureRetryCount) {
+ }
+ catch (Exception ex) when (i != Configuration.InternalBatchFailureRetryCount)
+ {
Log.Info("APNS-CLIENT[{0}]: Retrying Batch: Batch ID={1}, Error={2}", id, batchId, ex);
}
}
@@ -156,11 +168,18 @@ async Task SendBatch ()
foreach (var n in toSend)
sent.Add (new SentNotification (n));
}
-
- } catch (Exception ex) {
+ }
+ catch (ApnsConnectionException ex)
+ {
Log.Error ("APNS-CLIENT[{0}]: Send Batch Error: Batch ID={1}, Error={2}", id, batchId, ex);
foreach (var n in toSend)
n.CompleteFailed (new ApnsNotificationException (ApnsNotificationErrorStatusCode.ConnectionError, n.Notification, ex));
+ return;
+ }
+ catch (Exception ex) {
+ Log.Error ("APNS-CLIENT[{0}]: Send Batch Error: Batch ID={1}, Error={2}", id, batchId, ex);
+ foreach (var n in toSend)
+ n.CompleteFailed(new ApnsNotificationException(ApnsNotificationErrorStatusCode.ConnectionError, n.Notification, ex));
}
Log.Info ("APNS-Client[{0}]: Sent Batch, waiting for possible response...", id);
@@ -239,7 +258,7 @@ async Task Reader ()
sent.Clear ();
return;
}
-
+
// If we make it here, we did get data back, so we have errors
Log.Info ("APNS-Client[{0}]: Batch (ID={1}) completed with error response...", id, batchId);
@@ -321,25 +340,48 @@ async Task connect ()
Log.Info ("APNS-Client[{0}]: Connecting (Batch ID={1})", id, batchId);
- client = new TcpClient ();
+ client = new TcpClient();
- try {
- await client.ConnectAsync (Configuration.Host, Configuration.Port).ConfigureAwait (false);
+ try
+ {
+ if (!Configuration.UseProxy)
+ {
+ await client.ConnectAsync (Configuration.Host, Configuration.Port).ConfigureAwait (false);
+ }
+ else
+ {
+ var proxyHelper = new ProxyHelper { ProxyConnectionExceptionCreator = (message) => new ApnsConnectionException(message) };
+ proxyHelper.BeforeConnect += () => Log.Info("APNS-Client[{0}]: Connecting Proxy (Batch ID={1})", id, batchId);
+ proxyHelper.AfterConnect += (status) => Log.Info("APNS-Client[{0}]: Proxy Connected (Batch ID={1}) : {2}", id, batchId, status);
+ await proxyHelper.Connect(client, Configuration.Host, Configuration.Port, Configuration.ProxyHost, Configuration.ProxyPort, Configuration.ProxyCredentials).ConfigureAwait(false);
+ }
//Set keep alive on the socket may help maintain our APNS connection
- try {
- client.Client.SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
- } catch {
+ try
+ {
+ client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
+ }
+ catch
+ {
}
//Really not sure if this will work on MONO....
// This may help windows azure users
- try {
- SetSocketKeepAliveValues (client.Client, (int)Configuration.KeepAlivePeriod.TotalMilliseconds, (int)Configuration.KeepAliveRetryPeriod.TotalMilliseconds);
- } catch {
+ try
+ {
+ SetSocketKeepAliveValues(client.Client, (int)Configuration.KeepAlivePeriod.TotalMilliseconds, (int)Configuration.KeepAliveRetryPeriod.TotalMilliseconds);
}
- } catch (Exception ex) {
- throw new ApnsConnectionException ("Failed to Connect, check your firewall settings!", ex);
+ catch
+ {
+ }
+ }
+ catch (ApnsConnectionException)
+ {
+ throw;
+ }
+ catch (Exception ex)
+ {
+ throw new ApnsConnectionException("Failed to Connect, check your firewall settings!", ex);
}
// We can configure skipping ssl all together, ie: if we want to hit a test server
@@ -354,7 +396,8 @@ async Task connect ()
(sender, targetHost, localCerts, remoteCert, acceptableIssuers) => certificate);
try {
- stream.AuthenticateAsClient (Configuration.Host, certificates, System.Security.Authentication.SslProtocols.Tls, false);
+ var tls = System.Security.Authentication.SslProtocols.Tls | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls12;
+ stream.AuthenticateAsClient (Configuration.Host, certificates, tls, false);
} catch (System.Security.Authentication.AuthenticationException ex) {
throw new ApnsConnectionException ("SSL Stream Failed to Authenticate as Client", ex);
}
diff --git a/PushSharp.Apple/ApnsFeedbackService.cs b/PushSharp.Apple/ApnsFeedbackService.cs
index 57fb887a..d238d097 100644
--- a/PushSharp.Apple/ApnsFeedbackService.cs
+++ b/PushSharp.Apple/ApnsFeedbackService.cs
@@ -8,6 +8,7 @@
using System.Net.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
+using PushSharp.Common;
namespace PushSharp.Apple
{
@@ -24,6 +25,11 @@ public FeedbackService (ApnsConfiguration configuration)
public event FeedbackReceivedDelegate FeedbackReceived;
public void Check ()
+ {
+ this.GetTokenExpirations();
+
+ }
+ public IEnumerable GetTokenExpirations()
{
var encoding = Encoding.ASCII;
@@ -32,44 +38,61 @@ public void Check ()
var certificates = new X509CertificateCollection();
certificates.Add(certificate);
- var client = new TcpClient (Configuration.FeedbackHost, Configuration.FeedbackPort);
+ var client = new TcpClient();
+ Log.Info("APNS-FeedbackService: Connecting");
+ if (Configuration.UseProxy)
+ {
+ var proxyHelper = new ProxyHelper { ProxyConnectionExceptionCreator = (message) => new ApnsConnectionException(message) };
+ proxyHelper.BeforeConnect += () => Log.Info("APNS-FeedbackService: Connecting Proxy");
+ proxyHelper.AfterConnect += (status) => Log.Info("APNS-FeedbackService: Proxy Connected : {0}", status);
+ proxyHelper.Connect(client, Configuration.FeedbackHost, Configuration.FeedbackPort, Configuration.ProxyHost, Configuration.ProxyPort, Configuration.ProxyCredentials).Wait();
+ }
+ else
+ {
+ client.Connect(Configuration.FeedbackHost, Configuration.FeedbackPort);
+ }
+ Log.Info("APNS-FeedbackService: Connected");
- var stream = new SslStream (client.GetStream(), true,
+ var stream = new SslStream(client.GetStream(), true,
(sender, cert, chain, sslErrs) => { return true; },
(sender, targetHost, localCerts, remoteCert, acceptableIssuers) => { return certificate; });
- stream.AuthenticateAsClient(Configuration.FeedbackHost, certificates, System.Security.Authentication.SslProtocols.Tls, false);
+ var tls = System.Security.Authentication.SslProtocols.Tls | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls12;
+ stream.AuthenticateAsClient(Configuration.FeedbackHost, certificates, tls, false);
//Set up
byte[] buffer = new byte[4096];
int recd = 0;
- var data = new List ();
+ var data = new List();
+
+ Log.Info("APNS-FeedbackService: Getting expirations");
//Get the first feedback
recd = stream.Read(buffer, 0, buffer.Length);
+ var tokenBatch = new List();
//Continue while we have results and are not disposing
while (recd > 0)
{
// Add the received data to a list buffer to work with (easier to manipulate)
for (int i = 0; i < recd; i++)
- data.Add (buffer [i]);
-
+ data.Add(buffer[i]);
+
//Process each complete notification "packet" available in the buffer
while (data.Count >= (4 + 2 + 32)) // Minimum size for a valid packet
{
- var secondsBuffer = data.GetRange (0, 4).ToArray ();
- var tokenLengthBuffer = data.GetRange (4, 2).ToArray ();
+ var secondsBuffer = data.GetRange(0, 4).ToArray();
+ var tokenLengthBuffer = data.GetRange(4, 2).ToArray();
// Get our seconds since epoch
// Check endianness and reverse if needed
if (BitConverter.IsLittleEndian)
- Array.Reverse (secondsBuffer);
- var seconds = BitConverter.ToInt32 (secondsBuffer, 0);
+ Array.Reverse(secondsBuffer);
+ var seconds = BitConverter.ToInt32(secondsBuffer, 0);
//Add seconds since 1970 to that date, in UTC
- var timestamp = new DateTime (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds (seconds);
+ var timestamp = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(seconds);
//flag to allow feedback times in UTC or local, but default is local
if (!Configuration.FeedbackTimeIsUTC)
@@ -77,50 +100,68 @@ public void Check ()
if (BitConverter.IsLittleEndian)
- Array.Reverse (tokenLengthBuffer);
- var tokenLength = BitConverter.ToInt16 (tokenLengthBuffer, 0);
+ Array.Reverse(tokenLengthBuffer);
+ var tokenLength = BitConverter.ToInt16(tokenLengthBuffer, 0);
- if (data.Count >= 4 + 2 + tokenLength) {
+ if (data.Count >= 4 + 2 + tokenLength)
+ {
- var tokenBuffer = data.GetRange (6, tokenLength).ToArray ();
+ var tokenBuffer = data.GetRange(6, tokenLength).ToArray();
// Strings shouldn't care about endian-ness... this shouldn't be reversed
//if (BitConverter.IsLittleEndian)
// Array.Reverse (tokenBuffer);
- var token = BitConverter.ToString (tokenBuffer).Replace ("-", "").ToLower ().Trim ();
+ var token = BitConverter.ToString(tokenBuffer).Replace("-", "").ToLower().Trim();
// Remove what we parsed from the buffer
- data.RemoveRange (0, 4 + 2 + tokenLength);
+ data.RemoveRange(0, 4 + 2 + tokenLength);
+ tokenBatch.Add(new ApnsTokeExpirationInfo(token, timestamp));
// Raise the event to the consumer
var evt = FeedbackReceived;
if (evt != null)
- evt (token, timestamp);
- } else {
+ evt(token, timestamp);
+
+ }
+ else
+ {
continue;
}
-
}
//Read the next feedback
- recd = stream.Read (buffer, 0, buffer.Length);
+ recd = stream.Read(buffer, 0, buffer.Length);
}
try
{
- stream.Close ();
+ stream.Close();
stream.Dispose();
}
catch { }
- try
+ try
{
- client.Client.Shutdown (SocketShutdown.Both);
- client.Client.Dispose ();
+ client.Client.Shutdown(SocketShutdown.Both);
+ client.Client.Dispose();
}
catch { }
- try { client.Close (); } catch { }
+ try { client.Close(); } catch { }
+ Log.Info("APNS-FeedbackService: {0} expiration(s) received.", tokenBatch.Count);
+ return tokenBatch;
}
}
+
+ public class ApnsTokeExpirationInfo
+ {
+ public ApnsTokeExpirationInfo(string token, DateTime timestamp)
+ {
+ this.Token = token;
+ this.Timestamp = timestamp;
+ }
+
+ public string Token { get; private set; }
+ public DateTime Timestamp { get; private set; }
+ }
}
diff --git a/PushSharp.Apple/ApnsHttp2Configuration.cs b/PushSharp.Apple/ApnsHttp2Configuration.cs
deleted file mode 100644
index d3ba0e76..00000000
--- a/PushSharp.Apple/ApnsHttp2Configuration.cs
+++ /dev/null
@@ -1,156 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Security.Cryptography.X509Certificates;
-
-namespace PushSharp.Apple
-{
- public class ApnsHttp2Configuration
- {
- #region Constants
- const string APNS_SANDBOX_HOST = "api.development.push.apple.com";
- const string APNS_PRODUCTION_HOST = "api.push.apple.com";
-
- const uint APNS_SANDBOX_PORT = 443;
- const uint APNS_PRODUCTION_PORT = 443;
- #endregion
-
- public ApnsHttp2Configuration (ApnsServerEnvironment serverEnvironment, string certificateFile, string certificateFilePwd)
- : this (serverEnvironment, System.IO.File.ReadAllBytes (certificateFile), certificateFilePwd)
- {
- }
-
- public ApnsHttp2Configuration (ApnsServerEnvironment serverEnvironment, byte[] certificateData, string certificateFilePwd)
- : this (serverEnvironment, new X509Certificate2 (certificateData, certificateFilePwd,
- X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable))
- {
- }
-
- public ApnsHttp2Configuration (string overrideHost, uint overridePort, bool skipSsl = true)
- {
- SkipSsl = skipSsl;
-
- Initialize (ApnsServerEnvironment.Sandbox, null);
-
- OverrideServer (overrideHost, overridePort);
- }
-
- public ApnsHttp2Configuration (ApnsServerEnvironment serverEnvironment, X509Certificate2 certificate)
- {
- Initialize (serverEnvironment, certificate);
- }
-
- void Initialize (ApnsServerEnvironment serverEnvironment, X509Certificate2 certificate)
- {
- var production = serverEnvironment == ApnsServerEnvironment.Production;
-
- Host = production ? APNS_PRODUCTION_HOST : APNS_SANDBOX_HOST;
- Port = production ? APNS_PRODUCTION_PORT : APNS_SANDBOX_PORT;
-
- Certificate = certificate;
-
- MillisecondsToWaitBeforeMessageDeclaredSuccess = 3000;
- ConnectionTimeout = 10000;
- MaxConnectionAttempts = 3;
-
- FeedbackIntervalMinutes = 10;
- FeedbackTimeIsUTC = false;
-
- AdditionalCertificates = new List ();
- AddLocalAndMachineCertificateStores = false;
-
- CheckIsApnsCertificate ();
-
- ValidateServerCertificate = false;
-
- KeepAlivePeriod = TimeSpan.FromMinutes (20);
- KeepAliveRetryPeriod = TimeSpan.FromSeconds (30);
-
- InternalBatchSize = 1000;
- InternalBatchingWaitPeriod = TimeSpan.FromMilliseconds (750);
-
- InternalBatchFailureRetryCount = 1;
- }
-
-
- void CheckIsApnsCertificate ()
- {
- if (Certificate != null) {
- var issuerName = Certificate.IssuerName.Name;
- var commonName = Certificate.SubjectName.Name;
-
- if (!issuerName.Contains ("Apple"))
- throw new ApnsConnectionException ("Your Certificate does not appear to be issued by Apple! Please check to ensure you have the correct certificate!");
- if (!commonName.Contains ("Apple Push Services:"))
- throw new ApnsConnectionException ("Your Certificate is not in the new combined Sandbox/Production APNS certificate format, please create a new single certificate to use");
-
- } else {
- throw new ApnsConnectionException ("You must provide a Certificate to connect to APNS with!");
- }
- }
-
- public void OverrideServer (string host, uint port)
- {
- Host = host;
- Port = port;
- }
-
- public string Host { get; private set; }
-
- public uint Port { get; private set; }
-
- public X509Certificate2 Certificate { get; private set; }
-
- public List AdditionalCertificates { get; private set; }
-
- public bool AddLocalAndMachineCertificateStores { get; set; }
-
- public bool SkipSsl { get; set; }
-
- public int MillisecondsToWaitBeforeMessageDeclaredSuccess { get; set; }
-
- public int FeedbackIntervalMinutes { get; set; }
-
- public bool FeedbackTimeIsUTC { get; set; }
-
- public bool ValidateServerCertificate { get; set; }
-
- public int ConnectionTimeout { get; set; }
-
- public int MaxConnectionAttempts { get; set; }
-
- ///
- /// The internal connection to APNS servers batches notifications to send before waiting for errors for a short time.
- /// This value will set a maximum size per batch. The default value is 1000. You probably do not want this higher than 7500.
- ///
- /// The size of the internal batch.
- public int InternalBatchSize { get; set; }
-
- ///
- /// How long the internal connection to APNS servers should idle while collecting notifications in a batch to send.
- /// Setting this value too low might result in many smaller batches being used.
- ///
- /// The internal batching wait period.
- public TimeSpan InternalBatchingWaitPeriod { get; set; }
-
- ///
- /// How many times the internal batch will retry to send in case of network failure. The default value is 1.
- ///
- /// The internal batch failure retry count.
- public int InternalBatchFailureRetryCount { get; set; }
-
- ///
- /// Gets or sets the keep alive period to set on the APNS socket
- ///
- public TimeSpan KeepAlivePeriod { get; set; }
-
- ///
- /// Gets or sets the keep alive retry period to set on the APNS socket
- ///
- public TimeSpan KeepAliveRetryPeriod { get; set; }
-
- public enum ApnsServerEnvironment {
- Sandbox,
- Production
- }
- }
-}
\ No newline at end of file
diff --git a/PushSharp.Apple/ApnsHttp2Connection.cs b/PushSharp.Apple/ApnsHttp2Connection.cs
deleted file mode 100644
index 543ec43c..00000000
--- a/PushSharp.Apple/ApnsHttp2Connection.cs
+++ /dev/null
@@ -1,135 +0,0 @@
-using System;
-using System.Security.Cryptography.X509Certificates;
-using System.Threading.Tasks;
-using System.Collections.Specialized;
-using System.Collections.Generic;
-using System.Text;
-using System.Linq;
-using Newtonsoft.Json.Linq;
-using System.Net;
-
-namespace PushSharp.Apple
-{
- public class ApnsHttp2Connection
- {
- static int ID = 0;
-
- public ApnsHttp2Connection (ApnsHttp2Configuration configuration)
- {
- id = ++ID;
- if (id >= int.MaxValue)
- ID = 0;
-
- Configuration = configuration;
-
- certificate = Configuration.Certificate;
-
- certificates = new X509CertificateCollection ();
-
- // Add local/machine certificate stores to our collection if requested
- if (Configuration.AddLocalAndMachineCertificateStores) {
- var store = new X509Store (StoreLocation.LocalMachine);
- certificates.AddRange (store.Certificates);
-
- store = new X509Store (StoreLocation.CurrentUser);
- certificates.AddRange (store.Certificates);
- }
-
- // Add optionally specified additional certs into our collection
- if (Configuration.AdditionalCertificates != null) {
- foreach (var addlCert in Configuration.AdditionalCertificates)
- certificates.Add (addlCert);
- }
-
- // Finally, add the main private cert for authenticating to our collection
- if (certificate != null)
- certificates.Add (certificate);
-
- var http2Settings = new HttpTwo.Http2ConnectionSettings (
- Configuration.Host,
- (uint)Configuration.Port,
- true,
- certificates);
-
- http2 = new HttpTwo.Http2Client (http2Settings);
- }
-
- public ApnsHttp2Configuration Configuration { get; private set; }
-
- X509CertificateCollection certificates;
- X509Certificate2 certificate;
- int id = 0;
- HttpTwo.Http2Client http2;
-
- public async Task Send (ApnsHttp2Notification notification)
- {
- var url = string.Format ("https://{0}:{1}/3/device/{2}",
- Configuration.Host,
- Configuration.Port,
- notification.DeviceToken);
- var uri = new Uri (url);
-
- var payload = notification.Payload.ToString ();
-
- var data = Encoding.ASCII.GetBytes (payload);
-
- var headers = new NameValueCollection ();
- headers.Add ("apns-id", notification.Uuid); // UUID
-
- if (notification.Expiration.HasValue) {
- var sinceEpoch = notification.Expiration.Value.ToUniversalTime () - new DateTime (1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
- var secondsSinceEpoch = (long)sinceEpoch.TotalSeconds;
- headers.Add ("apns-expiration", secondsSinceEpoch.ToString ()); //Epoch in seconds
- }
-
- if (notification.Priority.HasValue)
- headers.Add ("apns-priority", notification.Priority == ApnsPriority.Low ? "5" : "10"); // 5 or 10
-
- headers.Add ("content-length", data.Length.ToString ());
-
- if (!string.IsNullOrEmpty (notification.Topic))
- headers.Add ("apns-topic", notification.Topic); // string topic
-
- var response = await http2.Post (uri, headers, data);
-
- if (response.Status == HttpStatusCode.OK) {
- // Check for matching uuid's
- var responseUuid = response.Headers ["apns-id"];
- if (responseUuid != notification.Uuid)
- throw new Exception ("Mismatched APNS-ID header values");
- } else {
- // Try parsing json body
- var json = new JObject ();
-
- if (response.Body != null && response.Body.Length > 0) {
- var body = Encoding.ASCII.GetString (response.Body);
- json = JObject.Parse (body);
- }
-
- if (response.Status == HttpStatusCode.Gone) {
-
- var timestamp = DateTime.UtcNow;
- if (json != null && json["timestamp"] != null) {
- var sinceEpoch = json.Value ("timestamp");
- timestamp = new DateTime (1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddSeconds (sinceEpoch);
- }
-
- // Expired
- throw new PushSharp.Core.DeviceSubscriptonExpiredException {
- OldSubscriptionId = notification.DeviceToken,
- NewSubscriptionId = null,
- ExpiredAt = timestamp
- };
- }
-
- // Get the reason
- var reasonStr = json.Value ("reason");
-
- var reason = (ApnsHttp2FailureReason)Enum.Parse (typeof (ApnsHttp2FailureReason), reasonStr, true);
-
- throw new ApnsHttp2NotificationException (reason, notification);
- }
- }
- }
-}
-
diff --git a/PushSharp.Apple/ApnsHttp2Notification.cs b/PushSharp.Apple/ApnsHttp2Notification.cs
deleted file mode 100644
index 5a390d31..00000000
--- a/PushSharp.Apple/ApnsHttp2Notification.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-using System;
-using PushSharp.Core;
-using Newtonsoft.Json.Linq;
-using System.Net;
-using System.Text;
-using System.Collections.Generic;
-
-namespace PushSharp.Apple
-{
- public class ApnsHttp2Notification : INotification
- {
- ///
- /// Store whatever associated information you'd like here
- ///
- /// The tag.
- public object Tag { get; set; }
-
- ///
- /// Unique Identifier to match server responses with
- ///
- /// The UUID.
- public string Uuid { get; set; }
-
- ///
- /// Device Token to send notifications to
- ///
- /// The device token.
- public string DeviceToken { get; set; }
-
- ///
- /// JSON APNS Payload
- ///
- /// The payload.
- public JObject Payload { get; set; }
-
- ///
- /// The expiration date after which Apple will no longer store and forward this push notification.
- /// If no value is provided, an assumed value of one year from now is used. If you do not wish
- /// for Apple to store and forward, set this value to Notification.DoNotStore.
- ///
- public DateTime? Expiration { get; set; }
-
- public ApnsPriority? Priority { get; set; }
-
- public string Topic { get;set; }
-
- public const int MAX_PAYLOAD_SIZE = 4096;
- public static readonly DateTime DoNotStore = DateTime.MinValue;
-
- public ApnsHttp2Notification () : this (string.Empty, new JObject ())
- {
- }
-
- public ApnsHttp2Notification (string deviceToken) : this (deviceToken, new JObject ())
- {
- }
-
- public ApnsHttp2Notification (string deviceToken, JObject payload)
- {
- DeviceToken = deviceToken;
- Payload = payload;
-
- Uuid = Guid.NewGuid ().ToString ("D");
- }
-
- public bool IsDeviceRegistrationIdValid ()
- {
- var r = new System.Text.RegularExpressions.Regex (@"^[0-9A-F]+$", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
- return r.Match (DeviceToken).Success;
- }
-
- public override string ToString ()
- {
- try {
- if (Payload != null)
- return Payload.ToString ();
- } catch {
- }
-
- return "{}";
- }
- }
-
- public enum ApnsPriority
- {
- Low = 5,
- High = 10
- }
-}
diff --git a/PushSharp.Apple/ApnsHttp2ServiceConnection.cs b/PushSharp.Apple/ApnsHttp2ServiceConnection.cs
deleted file mode 100644
index 39d8587c..00000000
--- a/PushSharp.Apple/ApnsHttp2ServiceConnection.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-using System;
-using PushSharp.Core;
-using System.Threading.Tasks;
-
-namespace PushSharp.Apple
-{
- public class ApnsHttp2ServiceConnectionFactory : IServiceConnectionFactory
- {
- public ApnsHttp2ServiceConnectionFactory (ApnsHttp2Configuration configuration)
- {
- Configuration = configuration;
- }
-
- public ApnsHttp2Configuration Configuration { get; private set; }
-
- public IServiceConnection Create()
- {
- return new ApnsHttp2ServiceConnection (Configuration);
- }
- }
-
- public class ApnsHttp2ServiceBroker : ServiceBroker
- {
- public ApnsHttp2ServiceBroker (ApnsHttp2Configuration configuration) : base (new ApnsHttp2ServiceConnectionFactory (configuration))
- {
- }
- }
-
- public class ApnsHttp2ServiceConnection : IServiceConnection
- {
- readonly ApnsHttp2Connection connection;
-
- public ApnsHttp2ServiceConnection (ApnsHttp2Configuration configuration)
- {
- connection = new ApnsHttp2Connection (configuration);
- }
-
- public async Task Send (ApnsHttp2Notification notification)
- {
- await connection.Send (notification);
- }
- }
-}
diff --git a/PushSharp.Apple/ApnsNotification.cs b/PushSharp.Apple/ApnsNotification.cs
index b9a4ea9e..6044f636 100644
--- a/PushSharp.Apple/ApnsNotification.cs
+++ b/PushSharp.Apple/ApnsNotification.cs
@@ -1,9 +1,9 @@
using System;
-using PushSharp.Core;
using Newtonsoft.Json.Linq;
using System.Net;
using System.Text;
using System.Collections.Generic;
+using PushSharp.Common;
namespace PushSharp.Apple
{
diff --git a/PushSharp.Apple/ApnsServiceConnection.cs b/PushSharp.Apple/ApnsServiceConnection.cs
index 2dc760cb..21234223 100644
--- a/PushSharp.Apple/ApnsServiceConnection.cs
+++ b/PushSharp.Apple/ApnsServiceConnection.cs
@@ -1,6 +1,6 @@
using System;
-using PushSharp.Core;
using System.Threading.Tasks;
+using PushSharp.Common;
namespace PushSharp.Apple
{
diff --git a/PushSharp.Apple/Exceptions.cs b/PushSharp.Apple/Exceptions.cs
index 33d28192..b559f52e 100644
--- a/PushSharp.Apple/Exceptions.cs
+++ b/PushSharp.Apple/Exceptions.cs
@@ -1,5 +1,5 @@
using System;
-using PushSharp.Core;
+using PushSharp.Common;
namespace PushSharp.Apple
{
diff --git a/PushSharp.Apple/Properties/AssemblyInfo.cs b/PushSharp.Apple/Properties/AssemblyInfo.cs
deleted file mode 100644
index 3b074103..00000000
--- a/PushSharp.Apple/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
-
-[assembly: AssemblyTitle ("PushSharp.Apple")]
-[assembly: AssemblyDescription ("")]
-[assembly: AssemblyConfiguration ("")]
-[assembly: AssemblyCompany ("")]
-[assembly: AssemblyProduct ("")]
-[assembly: AssemblyCopyright ("redth")]
-[assembly: AssemblyTrademark ("")]
-[assembly: AssemblyCulture ("")]
-
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
-
-[assembly: AssemblyVersion ("1.0.*")]
-
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
-
diff --git a/PushSharp.Apple/PushSharp.Apple.csproj b/PushSharp.Apple/PushSharp.Apple.csproj
index 3c9344a0..e87e650f 100644
--- a/PushSharp.Apple/PushSharp.Apple.csproj
+++ b/PushSharp.Apple/PushSharp.Apple.csproj
@@ -1,58 +1,20 @@
-
-
+
- Debug
- AnyCPU
- {A9D99F80-FEEB-4E74-96C5-66F17103C773}
- Library
- PushSharp.Apple
+ netstandard2.0;net45;
PushSharp.Apple
- v4.5
- true
- ..\PushSharp-Signing.snk
-
-
- true
- full
- false
- bin\Debug
- DEBUG;
- prompt
- 4
- false
-
-
- full
- true
- bin\Release
- prompt
- 4
- false
+ PushSharp.Apple
+
-
-
- ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
- {2B44A8DA-60BC-4577-A2D7-D9D53F164B2E}
- PushSharp.Core
-
+
+
+
+
-
+
-
\ No newline at end of file
+
+
diff --git a/PushSharp.Apple/packages.config b/PushSharp.Apple/packages.config
deleted file mode 100644
index 505e5883..00000000
--- a/PushSharp.Apple/packages.config
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/PushSharp.Blackberry/BlackberryConnection.cs b/PushSharp.Blackberry/BlackberryConnection.cs
index 14f17573..6ec825fa 100644
--- a/PushSharp.Blackberry/BlackberryConnection.cs
+++ b/PushSharp.Blackberry/BlackberryConnection.cs
@@ -3,7 +3,7 @@
using System.Net;
using System.Xml.Linq;
using System.Linq;
-using PushSharp.Core;
+using PushSharp.Common;
namespace PushSharp.Blackberry
{
diff --git a/PushSharp.Blackberry/BlackberryNotification.cs b/PushSharp.Blackberry/BlackberryNotification.cs
index 64b1fa17..b778eb9c 100644
--- a/PushSharp.Blackberry/BlackberryNotification.cs
+++ b/PushSharp.Blackberry/BlackberryNotification.cs
@@ -1,9 +1,10 @@
using System;
-using PushSharp.Core;
using System.Collections.Generic;
using System.Xml.Linq;
using System.Text;
using System.Globalization;
+using System.Web;
+using PushSharp.Common;
namespace PushSharp.Blackberry
{
@@ -92,7 +93,7 @@ public string ToPapXml()
if (!string.IsNullOrEmpty(r.RecipientType))
{
- addrValue = string.Format("WAPPUSH={0}%3A{1}/TYPE={2}", System.Web.HttpUtility.UrlEncode(r.Recipient),
+ addrValue = string.Format("WAPPUSH={0}%3A{1}/TYPE={2}", HttpUtility.UrlEncode(r.Recipient),
r.Port, r.RecipientType);
}
diff --git a/PushSharp.Blackberry/Exceptions.cs b/PushSharp.Blackberry/Exceptions.cs
index be990fce..b9e86497 100644
--- a/PushSharp.Blackberry/Exceptions.cs
+++ b/PushSharp.Blackberry/Exceptions.cs
@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
-using PushSharp.Core;
+using PushSharp.Common;
namespace PushSharp.Blackberry
{
diff --git a/PushSharp.Blackberry/Properties/AssemblyInfo.cs b/PushSharp.Blackberry/Properties/AssemblyInfo.cs
deleted file mode 100644
index ba2f5b78..00000000
--- a/PushSharp.Blackberry/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
-
-[assembly: AssemblyTitle ("PushSharp.Blackberry")]
-[assembly: AssemblyDescription ("")]
-[assembly: AssemblyConfiguration ("")]
-[assembly: AssemblyCompany ("")]
-[assembly: AssemblyProduct ("")]
-[assembly: AssemblyCopyright ("redth")]
-[assembly: AssemblyTrademark ("")]
-[assembly: AssemblyCulture ("")]
-
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
-
-[assembly: AssemblyVersion ("1.0.*")]
-
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
-
diff --git a/PushSharp.Blackberry/PushSharp.Blackberry.csproj b/PushSharp.Blackberry/PushSharp.Blackberry.csproj
index 4e0e54c3..303ee08f 100644
--- a/PushSharp.Blackberry/PushSharp.Blackberry.csproj
+++ b/PushSharp.Blackberry/PushSharp.Blackberry.csproj
@@ -1,55 +1,22 @@
-
-
+
+
- Debug
- AnyCPU
- {9F972AE9-DE47-4C26-AEE0-97E8A14F2E12}
- Library
- PushSharp.Blackberry
+ netstandard2.0;net45;
PushSharp.Blackberry
- v4.5
- true
- ..\PushSharp-Signing.snk
-
-
- true
- full
- false
- bin\Debug
- DEBUG;
- prompt
- 4
- false
-
-
- full
- true
- bin\Release
- prompt
- 4
- false
+ PushSharp.Blackberry
+
-
-
-
-
-
+
-
-
-
-
-
-
-
-
+
+
+
+
-
+
-
- {2B44A8DA-60BC-4577-A2D7-D9D53F164B2E}
- PushSharp.Core
-
+
-
\ No newline at end of file
+
+
diff --git a/PushSharp.Core/Exceptions.cs b/PushSharp.Common/Exceptions.cs
similarity index 67%
rename from PushSharp.Core/Exceptions.cs
rename to PushSharp.Common/Exceptions.cs
index 4cfc29fb..d752880d 100644
--- a/PushSharp.Core/Exceptions.cs
+++ b/PushSharp.Common/Exceptions.cs
@@ -1,19 +1,10 @@
using System;
-using System.Collections.Generic;
-namespace PushSharp.Core
+namespace PushSharp.Common
{
- public class DeviceSubscriptionExpiredException : DeviceSubscriptonExpiredException
+ public class DeviceSubscriptionExpiredException : NotificationException
{
- public DeviceSubscriptionExpiredException (INotification notification) : base (notification)
- {
- }
- }
-
- [Obsolete ("Do not use this class directly, it has a typo in it, instead use DeviceSubscriptionExpiredException")]
- public class DeviceSubscriptonExpiredException : NotificationException
- {
- public DeviceSubscriptonExpiredException (INotification notification) : base ("Device Subscription has Expired", notification)
+ public DeviceSubscriptionExpiredException(INotification notification) : base ("Device Subscription has Expired", notification)
{
ExpiredAt = DateTime.UtcNow;
}
diff --git a/PushSharp.Core/INotification.cs b/PushSharp.Common/INotification.cs
similarity index 75%
rename from PushSharp.Core/INotification.cs
rename to PushSharp.Common/INotification.cs
index 23e26d0f..72777f56 100644
--- a/PushSharp.Core/INotification.cs
+++ b/PushSharp.Common/INotification.cs
@@ -1,6 +1,4 @@
-using System;
-
-namespace PushSharp.Core
+namespace PushSharp.Common
{
public interface INotification
{
diff --git a/PushSharp.Core/IServiceBroker.cs b/PushSharp.Common/IServiceBroker.cs
similarity index 95%
rename from PushSharp.Core/IServiceBroker.cs
rename to PushSharp.Common/IServiceBroker.cs
index 0aa82a75..5924e758 100644
--- a/PushSharp.Core/IServiceBroker.cs
+++ b/PushSharp.Common/IServiceBroker.cs
@@ -1,6 +1,6 @@
using System;
-namespace PushSharp.Core
+namespace PushSharp.Common
{
public interface IServiceBroker where TNotification : INotification
{
diff --git a/PushSharp.Core/IServiceConnection.cs b/PushSharp.Common/IServiceConnection.cs
similarity index 94%
rename from PushSharp.Core/IServiceConnection.cs
rename to PushSharp.Common/IServiceConnection.cs
index cfc1812c..8344e3b4 100644
--- a/PushSharp.Core/IServiceConnection.cs
+++ b/PushSharp.Common/IServiceConnection.cs
@@ -1,7 +1,7 @@
using System;
using System.Threading.Tasks;
-namespace PushSharp.Core
+namespace PushSharp.Common
{
public delegate void NotificationSuccessDelegate (TNotification notification) where TNotification : INotification;
public delegate void NotificationFailureDelegate (TNotification notification, AggregateException exception) where TNotification : INotification;
diff --git a/PushSharp.Core/IServiceConnectionFactory.cs b/PushSharp.Common/IServiceConnectionFactory.cs
similarity index 79%
rename from PushSharp.Core/IServiceConnectionFactory.cs
rename to PushSharp.Common/IServiceConnectionFactory.cs
index bb30597a..036aec70 100644
--- a/PushSharp.Core/IServiceConnectionFactory.cs
+++ b/PushSharp.Common/IServiceConnectionFactory.cs
@@ -1,6 +1,4 @@
-using System;
-
-namespace PushSharp.Core
+namespace PushSharp.Common
{
public interface IServiceConnectionFactory where TNotification : INotification
{
diff --git a/PushSharp.Core/Log.cs b/PushSharp.Common/Log.cs
similarity index 99%
rename from PushSharp.Core/Log.cs
rename to PushSharp.Common/Log.cs
index fd749d2d..11a0b4c2 100644
--- a/PushSharp.Core/Log.cs
+++ b/PushSharp.Common/Log.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Diagnostics;
-namespace PushSharp.Core
+namespace PushSharp.Common
{
[Flags]
public enum LogLevel
diff --git a/PushSharp.Core/NotificationBlockingCollection.cs b/PushSharp.Common/NotificationBlockingCollection.cs
similarity index 71%
rename from PushSharp.Core/NotificationBlockingCollection.cs
rename to PushSharp.Common/NotificationBlockingCollection.cs
index 7cd4352b..00d8fa3a 100644
--- a/PushSharp.Core/NotificationBlockingCollection.cs
+++ b/PushSharp.Common/NotificationBlockingCollection.cs
@@ -1,6 +1,4 @@
-using System;
-
-namespace PushSharp.Core
+namespace PushSharp.Common
{
public class NotificationBlockingCollection
{
diff --git a/PushSharp.Common/Properties/PublishProfiles/FolderProfile.pubxml b/PushSharp.Common/Properties/PublishProfiles/FolderProfile.pubxml
new file mode 100644
index 00000000..296ffbdb
--- /dev/null
+++ b/PushSharp.Common/Properties/PublishProfiles/FolderProfile.pubxml
@@ -0,0 +1,13 @@
+
+
+
+
+ FileSystem
+ Release
+ netstandard2.0
+ bin\Release\PublishOutput
+
+
\ No newline at end of file
diff --git a/PushSharp.Common/ProxyHelper.cs b/PushSharp.Common/ProxyHelper.cs
new file mode 100644
index 00000000..3a55051a
--- /dev/null
+++ b/PushSharp.Common/ProxyHelper.cs
@@ -0,0 +1,86 @@
+using System;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PushSharp.Common
+{
+ public delegate void BeforeConnectDelegate();
+
+ public delegate void AfterConnectDelegate(string status);
+
+ public class ProxyHelper
+ {
+ public Func ProxyConnectionExceptionCreator { get; set; }
+ public event BeforeConnectDelegate BeforeConnect;
+ public event AfterConnectDelegate AfterConnect;
+
+ public async Task Connect(TcpClient client, string targetHost, int targetPort, string proxyHost, int proxyPort, NetworkCredential proxyCredential = null)
+ {
+ this.OnBeforeConnect();
+ await client.ConnectAsync(proxyHost, proxyPort).ConfigureAwait(false);
+ var stream = client.GetStream();
+ var authorization = string.Empty;
+ if (proxyCredential != null)
+ {
+ var credential = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{proxyCredential.UserName}:{proxyCredential.Password}"));
+ authorization = $"\r\nAuthorization: Basic {credential}";
+ }
+ var buffer =
+ Encoding.UTF8.GetBytes(
+ string.Format("CONNECT {0}:{1} HTTP/1.1\r\nHost: {0}:{1}{2}\r\nProxy-Connection: keep-alive\r\n\r\n", targetHost, targetPort, authorization));
+ await stream.WriteAsync(buffer, 0, buffer.Length);
+ await stream.FlushAsync();
+ buffer = new byte[client.Client.ReceiveBufferSize];
+ using (var resp = new MemoryStream())
+ {
+ do
+ {
+ var len = await stream.ReadAsync(buffer, 0, buffer.Length);
+ resp.Write(buffer, 0, len);
+ }
+ while (client.Client.Available > 0);
+ buffer = resp.ToArray();
+ }
+ var content = Encoding.UTF8.GetString(buffer);
+ var i = content.IndexOf('\r');
+ string statusCode;
+ if (i > 9)
+ {
+ statusCode = content.Substring(9, i - 9);
+ }
+ else
+ {
+ var max = content.Length;
+ if (max > 50)
+ {
+ max = 50;
+ }
+ var append = max == 50 ? "..." : string.Empty;
+ statusCode = content.Substring(0, max) + append;
+ }
+ this.OnAfterConnect(statusCode);
+ if (!statusCode.StartsWith("200"))
+ {
+ var fac = this.ProxyConnectionExceptionCreator;
+ if (fac != null)
+ {
+ throw fac($"Proxy returned {statusCode}. Check proxy settings and if it allows ssl through ports different of 443.");
+ }
+ throw new Exception($"Proxy returned {statusCode}. Check proxy settings and if it allows ssl through ports different of 443.");
+ }
+ }
+
+ protected virtual void OnBeforeConnect()
+ {
+ this.BeforeConnect?.Invoke();
+ }
+
+ protected virtual void OnAfterConnect(string status)
+ {
+ this.AfterConnect?.Invoke(status);
+ }
+ }
+}
\ No newline at end of file
diff --git a/PushSharp.Core/PushHttpClient.cs b/PushSharp.Common/PushHttpClient.cs
similarity index 99%
rename from PushSharp.Core/PushHttpClient.cs
rename to PushSharp.Common/PushHttpClient.cs
index cbc6fcfd..26f90b9a 100644
--- a/PushSharp.Core/PushHttpClient.cs
+++ b/PushSharp.Common/PushHttpClient.cs
@@ -1,10 +1,10 @@
using System;
+using System.IO;
using System.Net;
using System.Text;
-using System.IO;
using System.Threading.Tasks;
-namespace PushSharp.Core
+namespace PushSharp.Common
{
public static class PushHttpClient
{
diff --git a/PushSharp.Common/PushSharp.Common.csproj b/PushSharp.Common/PushSharp.Common.csproj
new file mode 100644
index 00000000..284058f9
--- /dev/null
+++ b/PushSharp.Common/PushSharp.Common.csproj
@@ -0,0 +1,7 @@
+
+
+
+ netstandard2.0;net45;
+
+
+
diff --git a/PushSharp.Core/ServiceBroker.cs b/PushSharp.Common/ServiceBroker.cs
similarity index 99%
rename from PushSharp.Core/ServiceBroker.cs
rename to PushSharp.Common/ServiceBroker.cs
index 4b87f7b1..4b93a587 100644
--- a/PushSharp.Core/ServiceBroker.cs
+++ b/PushSharp.Common/ServiceBroker.cs
@@ -1,12 +1,12 @@
using System;
-using System.Linq;
using System.Collections.Concurrent;
-using System.Threading.Tasks;
-using System.Threading;
using System.Collections.Generic;
+using System.Linq;
using System.Net;
+using System.Threading;
+using System.Threading.Tasks;
-namespace PushSharp.Core
+namespace PushSharp.Common
{
public class ServiceBroker : IServiceBroker where TNotification : INotification
{
diff --git a/PushSharp.Core/ServiceBrokerConfiguration.cs b/PushSharp.Common/ServiceBrokerConfiguration.cs
similarity index 94%
rename from PushSharp.Core/ServiceBrokerConfiguration.cs
rename to PushSharp.Common/ServiceBrokerConfiguration.cs
index 5db03aab..b7b58a2a 100644
--- a/PushSharp.Core/ServiceBrokerConfiguration.cs
+++ b/PushSharp.Common/ServiceBrokerConfiguration.cs
@@ -1,6 +1,4 @@
-using System;
-
-namespace PushSharp.Core
+namespace PushSharp.Common
{
public class ServiceBrokerConfiguration // : IPushServiceSettings
{
diff --git a/PushSharp.Core.1.0.0.nupkg b/PushSharp.Core.1.0.0.nupkg
new file mode 100644
index 00000000..44453446
Binary files /dev/null and b/PushSharp.Core.1.0.0.nupkg differ
diff --git a/PushSharp.Core.sln b/PushSharp.Core.sln
new file mode 100644
index 00000000..848ca707
--- /dev/null
+++ b/PushSharp.Core.sln
@@ -0,0 +1,79 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26730.12
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Platforms", "Platforms", "{2B7243CB-60A5-4682-802B-B7EC3DEBCF9A}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Support Libraries", "Support Libraries", "{6449DAB1-E76A-4354-B633-CC6AC53BB757}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PushSharp.Amazon", "PushSharp.Amazon\PushSharp.Amazon.csproj", "{B799D03A-C50F-40BC-B2F5-CF236FDBDFE5}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PushSharp.Apple", "PushSharp.Apple\PushSharp.Apple.csproj", "{01EB608A-B2B0-4A68-81FE-07F572F93911}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PushSharp.Tests", "PushSharp.Tests\PushSharp.Tests.csproj", "{FFD8E1A2-FCF4-4C28-AD7C-23AA237963FF}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PushSharp.Blackberry", "PushSharp.Blackberry\PushSharp.Blackberry.csproj", "{B5269845-C8E9-4642-85E8-9225A93CA8B3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PushSharp.Firefox", "PushSharp.Firefox\PushSharp.Firefox.csproj", "{94323AB5-1FF9-4B9B-8D6B-26E73F3EFB86}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PushSharp.Google", "PushSharp.Google\PushSharp.Google.csproj", "{DEC9D5A4-22E0-4CA4-B05D-C84BE2707DDC}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PushSharp.Windows", "PushSharp.Windows\PushSharp.Windows.csproj", "{7C4BD0D5-1D92-42FB-BF16-84C6B82EE6CE}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PushSharp.Common", "PushSharp.Common\PushSharp.Common.csproj", "{CB5CB153-B5A5-4B93-86AE-35067CE970A5}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B799D03A-C50F-40BC-B2F5-CF236FDBDFE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B799D03A-C50F-40BC-B2F5-CF236FDBDFE5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B799D03A-C50F-40BC-B2F5-CF236FDBDFE5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B799D03A-C50F-40BC-B2F5-CF236FDBDFE5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {01EB608A-B2B0-4A68-81FE-07F572F93911}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {01EB608A-B2B0-4A68-81FE-07F572F93911}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {01EB608A-B2B0-4A68-81FE-07F572F93911}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {01EB608A-B2B0-4A68-81FE-07F572F93911}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FFD8E1A2-FCF4-4C28-AD7C-23AA237963FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FFD8E1A2-FCF4-4C28-AD7C-23AA237963FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FFD8E1A2-FCF4-4C28-AD7C-23AA237963FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FFD8E1A2-FCF4-4C28-AD7C-23AA237963FF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B5269845-C8E9-4642-85E8-9225A93CA8B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B5269845-C8E9-4642-85E8-9225A93CA8B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B5269845-C8E9-4642-85E8-9225A93CA8B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B5269845-C8E9-4642-85E8-9225A93CA8B3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {94323AB5-1FF9-4B9B-8D6B-26E73F3EFB86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {94323AB5-1FF9-4B9B-8D6B-26E73F3EFB86}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {94323AB5-1FF9-4B9B-8D6B-26E73F3EFB86}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {94323AB5-1FF9-4B9B-8D6B-26E73F3EFB86}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DEC9D5A4-22E0-4CA4-B05D-C84BE2707DDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DEC9D5A4-22E0-4CA4-B05D-C84BE2707DDC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DEC9D5A4-22E0-4CA4-B05D-C84BE2707DDC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DEC9D5A4-22E0-4CA4-B05D-C84BE2707DDC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7C4BD0D5-1D92-42FB-BF16-84C6B82EE6CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7C4BD0D5-1D92-42FB-BF16-84C6B82EE6CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7C4BD0D5-1D92-42FB-BF16-84C6B82EE6CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7C4BD0D5-1D92-42FB-BF16-84C6B82EE6CE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CB5CB153-B5A5-4B93-86AE-35067CE970A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CB5CB153-B5A5-4B93-86AE-35067CE970A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CB5CB153-B5A5-4B93-86AE-35067CE970A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CB5CB153-B5A5-4B93-86AE-35067CE970A5}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {B799D03A-C50F-40BC-B2F5-CF236FDBDFE5} = {2B7243CB-60A5-4682-802B-B7EC3DEBCF9A}
+ {01EB608A-B2B0-4A68-81FE-07F572F93911} = {2B7243CB-60A5-4682-802B-B7EC3DEBCF9A}
+ {B5269845-C8E9-4642-85E8-9225A93CA8B3} = {2B7243CB-60A5-4682-802B-B7EC3DEBCF9A}
+ {94323AB5-1FF9-4B9B-8D6B-26E73F3EFB86} = {2B7243CB-60A5-4682-802B-B7EC3DEBCF9A}
+ {DEC9D5A4-22E0-4CA4-B05D-C84BE2707DDC} = {2B7243CB-60A5-4682-802B-B7EC3DEBCF9A}
+ {7C4BD0D5-1D92-42FB-BF16-84C6B82EE6CE} = {2B7243CB-60A5-4682-802B-B7EC3DEBCF9A}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {904C7FEA-C00A-44F3-9BB8-36D8F674BAD5}
+ EndGlobalSection
+EndGlobal
diff --git a/PushSharp.Core/Properties/AssemblyInfo.cs b/PushSharp.Core/Properties/AssemblyInfo.cs
deleted file mode 100644
index 3b9c03a1..00000000
--- a/PushSharp.Core/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
-
-[assembly: AssemblyTitle ("PushSharp.Core")]
-[assembly: AssemblyDescription ("")]
-[assembly: AssemblyConfiguration ("")]
-[assembly: AssemblyCompany ("")]
-[assembly: AssemblyProduct ("")]
-[assembly: AssemblyCopyright ("redth")]
-[assembly: AssemblyTrademark ("")]
-[assembly: AssemblyCulture ("")]
-
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
-
-[assembly: AssemblyVersion ("1.0.*")]
-
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
-
diff --git a/PushSharp.Core/PushSharp.Core.csproj b/PushSharp.Core/PushSharp.Core.csproj
deleted file mode 100644
index e46f9756..00000000
--- a/PushSharp.Core/PushSharp.Core.csproj
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
- Debug
- AnyCPU
- {2B44A8DA-60BC-4577-A2D7-D9D53F164B2E}
- Library
- PushSharp.Core
- PushSharp.Core
- v4.5
- true
- ..\PushSharp-Signing.snk
-
-
- true
- full
- false
- bin\Debug
- DEBUG;
- prompt
- 4
- false
-
-
- full
- true
- bin\Release
- prompt
- 4
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/PushSharp.Firefox/Exceptions.cs b/PushSharp.Firefox/Exceptions.cs
index 406fb1fd..be14b270 100644
--- a/PushSharp.Firefox/Exceptions.cs
+++ b/PushSharp.Firefox/Exceptions.cs
@@ -1,5 +1,5 @@
using System;
-using PushSharp.Core;
+using PushSharp.Common;
namespace PushSharp.Firefox
{
diff --git a/PushSharp.Firefox/FirefoxConnection.cs b/PushSharp.Firefox/FirefoxConnection.cs
index acdd8afe..3944b0ff 100644
--- a/PushSharp.Firefox/FirefoxConnection.cs
+++ b/PushSharp.Firefox/FirefoxConnection.cs
@@ -1,9 +1,9 @@
using System;
-using PushSharp.Core;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net;
using System.Net.Http.Headers;
+using PushSharp.Common;
namespace PushSharp.Firefox
{
diff --git a/PushSharp.Firefox/FirefoxNotification.cs b/PushSharp.Firefox/FirefoxNotification.cs
index cbf1fd0c..7b5ee1e9 100644
--- a/PushSharp.Firefox/FirefoxNotification.cs
+++ b/PushSharp.Firefox/FirefoxNotification.cs
@@ -1,5 +1,5 @@
using System;
-using PushSharp.Core;
+using PushSharp.Common;
namespace PushSharp.Firefox
{
diff --git a/PushSharp.Firefox/Properties/AssemblyInfo.cs b/PushSharp.Firefox/Properties/AssemblyInfo.cs
deleted file mode 100644
index ccdecdce..00000000
--- a/PushSharp.Firefox/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
-
-[assembly: AssemblyTitle ("PushSharp.Firefox")]
-[assembly: AssemblyDescription ("")]
-[assembly: AssemblyConfiguration ("")]
-[assembly: AssemblyCompany ("")]
-[assembly: AssemblyProduct ("")]
-[assembly: AssemblyCopyright ("redth")]
-[assembly: AssemblyTrademark ("")]
-[assembly: AssemblyCulture ("")]
-
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
-
-[assembly: AssemblyVersion ("1.0.*")]
-
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
-
diff --git a/PushSharp.Firefox/PushSharp.Firefox.csproj b/PushSharp.Firefox/PushSharp.Firefox.csproj
index 4fb18fb7..423e97be 100644
--- a/PushSharp.Firefox/PushSharp.Firefox.csproj
+++ b/PushSharp.Firefox/PushSharp.Firefox.csproj
@@ -1,50 +1,19 @@
-
-
+
+
- Debug
- AnyCPU
- {54A4C1F9-6571-4086-BB4B-EC202138AF00}
- Library
- PushSharp.Firefox
- PushSharp.Firefox
- v4.5
- true
- ..\PushSharp-Signing.snk
-
-
- true
- full
- false
- bin\Debug
- DEBUG;
- prompt
- 4
- false
-
-
- full
- true
- bin\Release
- prompt
- 4
- false
+ netstandard2.0;net45;
+
-
-
+
-
-
-
-
-
-
+
+
+
-
+
-
- {2B44A8DA-60BC-4577-A2D7-D9D53F164B2E}
- PushSharp.Core
-
+
-
\ No newline at end of file
+
+
diff --git a/PushSharp.Google/Exceptions.cs b/PushSharp.Google/Exceptions.cs
index b27da6ec..cd059c7a 100644
--- a/PushSharp.Google/Exceptions.cs
+++ b/PushSharp.Google/Exceptions.cs
@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
-using PushSharp.Core;
+using PushSharp.Common;
namespace PushSharp.Google
{
diff --git a/PushSharp.Google/GcmConfiguration.cs b/PushSharp.Google/GcmConfiguration.cs
index 91f320ff..31845726 100644
--- a/PushSharp.Google/GcmConfiguration.cs
+++ b/PushSharp.Google/GcmConfiguration.cs
@@ -1,10 +1,11 @@
using System;
+using System.Net;
namespace PushSharp.Google
{
public class GcmConfiguration
{
- private const string GCM_SEND_URL = "https://gcm-http.googleapis.com/gcm/send";
+ private const string GCM_SEND_URL = "https://fcm.googleapis.com/fcm/send";
public GcmConfiguration (string senderAuthToken)
{
@@ -24,6 +25,30 @@ public GcmConfiguration (string optionalSenderID, string senderAuthToken, string
this.ValidateServerCertificate = false;
}
+ public void SetProxy(string host, int port)
+ {
+ UseProxy = true;
+ ProxyHost = host;
+ ProxyPort = port;
+ ProxyCredentials = CredentialCache.DefaultNetworkCredentials;
+ }
+
+ public void SetProxy(string host, int port, string username, string pass, string domain)
+ {
+ UseProxy = true;
+ ProxyHost = host;
+ ProxyPort = port;
+ ProxyCredentials = new NetworkCredential(username, pass, domain);
+ }
+
+ public bool UseProxy { get; private set; }
+
+ public string ProxyHost { get; private set; }
+
+ public int ProxyPort { get; private set; }
+
+ public NetworkCredential ProxyCredentials { get; private set; }
+
public string SenderID { get; private set; }
public string SenderAuthToken { get; private set; }
diff --git a/PushSharp.Google/GcmNotification.cs b/PushSharp.Google/GcmNotification.cs
index 28ba0599..4b45f1c9 100644
--- a/PushSharp.Google/GcmNotification.cs
+++ b/PushSharp.Google/GcmNotification.cs
@@ -2,9 +2,9 @@
using System.Runtime.Serialization;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
-using PushSharp.Core;
using System.Linq;
using Newtonsoft.Json;
+using PushSharp.Common;
namespace PushSharp.Google
{
@@ -26,7 +26,6 @@ public static GcmNotification ForSingleResult (GcmResponse response, int resultI
result.DryRun = response.OriginalNotification.DryRun;
result.Priority = response.OriginalNotification.Priority;
result.To = response.OriginalNotification.To;
- result.NotificationKey = response.OriginalNotification.NotificationKey;
return result;
}
@@ -44,7 +43,6 @@ public static GcmNotification ForSingleRegistrationId (GcmNotification msg, stri
result.ContentAvailable = msg.ContentAvailable;
result.DryRun = msg.DryRun;
result.Priority = msg.Priority;
- result.NotificationKey = msg.NotificationKey;
return result;
}
@@ -118,12 +116,6 @@ public bool IsDeviceRegistrationIdValid ()
[JsonProperty ("dry_run")]
public bool? DryRun { get; set; }
- ///
- /// A string that maps a single user to multiple registration IDs associated with that user. This allows a 3rd-party server to send a single message to multiple app instances (typically on multiple devices) owned by a single user.
- ///
- [Obsolete ("Deprecated on GCM Server API. Use Device Group Messaging to send to multiple devices.")]
- public string NotificationKey { get; set; }
-
///
/// A string containing the package name of your application. When set, messages will only be sent to registration IDs that match the package name
///
diff --git a/PushSharp.Google/GcmServiceConnection.cs b/PushSharp.Google/GcmServiceConnection.cs
index b3b539c5..299ec9c4 100644
--- a/PushSharp.Google/GcmServiceConnection.cs
+++ b/PushSharp.Google/GcmServiceConnection.cs
@@ -4,10 +4,10 @@
using System.Net.Http.Headers;
using Newtonsoft.Json.Linq;
using System.Net;
-using PushSharp.Core;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
+using PushSharp.Common;
namespace PushSharp.Google
{
@@ -38,8 +38,14 @@ public class GcmServiceConnection : IServiceConnection
public GcmServiceConnection (GcmConfiguration configuration)
{
Configuration = configuration;
- http = new HttpClient ();
-
+ if (Configuration.UseProxy)
+ {
+ http = GetClientHTTPProxy(Configuration.ProxyHost, Configuration.ProxyPort, Configuration.ProxyCredentials);
+ }
+ else
+ {
+ http = new HttpClient();
+ }
http.DefaultRequestHeaders.UserAgent.Clear ();
http.DefaultRequestHeaders.UserAgent.Add (new ProductInfoHeaderValue ("PushSharp", "3.0"));
http.DefaultRequestHeaders.TryAddWithoutValidation ("Authorization", "key=" + Configuration.SenderAuthToken);
@@ -212,5 +218,31 @@ static GcmResponseStatus GetGcmResponseStatus (string str)
//Default
return GcmResponseStatus.Error;
}
+
+ private HttpClient GetClientHTTPProxy(string host, int port, NetworkCredential credentials)
+ {
+ HttpClient client = null;
+ try
+ {
+ string proxyUri = string.Format("{0}:{1}", host, port);
+ WebProxy proxy = new WebProxy(proxyUri, false)
+ {
+ Credentials = credentials
+ };
+ HttpClientHandler httpClientHandler = new HttpClientHandler()
+ {
+ Proxy = proxy,
+ PreAuthenticate = false
+ };
+ client = new HttpClient(httpClientHandler);
+ }
+ catch (Exception ex)
+ {
+ client = null;
+ Log.Error(ex.Message);
+ throw;
+ }
+ return client;
+ }
}
}
diff --git a/PushSharp.Google/Properties/AssemblyInfo.cs b/PushSharp.Google/Properties/AssemblyInfo.cs
deleted file mode 100644
index 2afce1ae..00000000
--- a/PushSharp.Google/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
-
-[assembly: AssemblyTitle ("PushSharp.Google")]
-[assembly: AssemblyDescription ("")]
-[assembly: AssemblyConfiguration ("")]
-[assembly: AssemblyCompany ("")]
-[assembly: AssemblyProduct ("")]
-[assembly: AssemblyCopyright ("redth")]
-[assembly: AssemblyTrademark ("")]
-[assembly: AssemblyCulture ("")]
-
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
-
-[assembly: AssemblyVersion ("1.0.*")]
-
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
-
diff --git a/PushSharp.Google/PushSharp.Google.csproj b/PushSharp.Google/PushSharp.Google.csproj
index 92d72f31..423e97be 100644
--- a/PushSharp.Google/PushSharp.Google.csproj
+++ b/PushSharp.Google/PushSharp.Google.csproj
@@ -1,61 +1,19 @@
-
-
+
+
- Debug
- AnyCPU
- {94F16497-471F-433F-A99E-C455FB2D7724}
- Library
- PushSharp.Google
- PushSharp.Google
- v4.5
- true
- ..\PushSharp-Signing.snk
-
-
- true
- full
- false
- bin\Debug
- DEBUG;
- prompt
- 4
- false
-
-
- full
- true
- bin\Release
- prompt
- 4
- false
+ netstandard2.0;net45;
+
-
-
-
-
-
-
- ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll
-
+
-
-
-
-
-
-
-
-
-
-
-
-
- {2B44A8DA-60BC-4577-A2D7-D9D53F164B2E}
- PushSharp.Core
-
+
+
+
+
-
+
-
\ No newline at end of file
+
+
diff --git a/PushSharp.Google/Xmpp/GcmXmppConfiguration.cs b/PushSharp.Google/Xmpp/GcmXmppConfiguration.cs
deleted file mode 100644
index fa186494..00000000
--- a/PushSharp.Google/Xmpp/GcmXmppConfiguration.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace PushSharp.Google
-{
- public class GcmXmppConfiguration
- {
- public GcmXmppConfiguration ()
- {
- Production = true;
- SenderIDs = new List ();
- }
-
- public const string GCM_XMPP_SERVER = "gcm.googleapis.com";
- public const string GCM_XMPP_PREPROD_SERVER = "gcm-preprod.googleapis.com";
- public const int GCM_XMPP_PORT = 5235;
- public const int GCM_XMPP_PREPROD_PORT = 5236;
-
- public List SenderIDs { get; set; }
- public string AuthenticationToken { get; set; }
-
- public string SaslAuthToken {
- get {
- var s = new StringBuilder ();
-
- foreach (var sender in SenderIDs)
- s.Append ("\0" + sender + "@gcm.googleapis.com");
-
- s.Append ("\0" + AuthenticationToken);
-
- return Convert.ToBase64String (Encoding.UTF8.GetBytes (s.ToString ()));
- }
- }
-
- public bool Production { get;set; }
-
- string overrideHost = string.Empty;
- int? overridePort = null;
-
- public string Host {
- get {
- if (!string.IsNullOrEmpty (overrideHost))
- return overrideHost;
-
- return Production ? GCM_XMPP_SERVER : GCM_XMPP_PREPROD_SERVER;
- }
- }
-
- public int Port {
- get {
- if (overridePort.HasValue)
- return overridePort.Value;
-
- return Production ? GCM_XMPP_PORT : GCM_XMPP_PREPROD_PORT;
- }
- }
- }
-}
-
diff --git a/PushSharp.Google/Xmpp/GcmXmppConnection.cs b/PushSharp.Google/Xmpp/GcmXmppConnection.cs
deleted file mode 100644
index 5c9b0be3..00000000
--- a/PushSharp.Google/Xmpp/GcmXmppConnection.cs
+++ /dev/null
@@ -1,323 +0,0 @@
-using System;
-using System.Net.Sockets;
-using System.Threading.Tasks;
-using System.Net.Security;
-using System.Xml;
-using System.Text;
-using System.IO;
-using System.Xml.Linq;
-using PushSharp.Core;
-using System.Security.Cryptography.X509Certificates;
-using System.Collections.Generic;
-
-namespace PushSharp.Google
-{
- public class GcmXmppConnection
- {
- public const string STREAM_ELEMENT_NAME = "stream";
- public const string SASL_AUTH_ELEMENT_NAME = "auth";
- public const string BIND_ELEMENT_NAME = "bind";
- public const string IQ_ELEMENT_NAME = "iq";
- public const string MESSAGE_ELEMENT_NAME = "message";
- public const string RESOURCE_ELEMENT_NAME = "resource";
- public const string MECHANISMS_ELEMENT_NAME = "mechanisms";
- public const string STREAM_PREFIX = "stream";
- public const string STREAM_NAMESPACE = "http://etherx.jabber.org/streams";
- public const string STREAM_PARAMS_NAMESPACE = "urn:ietf:params:xml:ns:xmpp-streams";
- public const string JABBER_NAMESPACE = "jabber:client";
- public const string GCM_MSG_NAMESPACE = "google:mobile:data";
- public const string SASL_NAMESPACE = "urn:ietf:params:xml:ns:xmpp-sasl";
- public const string BIND_NAMESPACE = "urn:ietf:params:xml:ns:xmpp-bind";
- public const int MAJOR_VERSION = 1;
- public const int MINOR_VERSION = 0;
-
- readonly XNamespace GCM_NS = GCM_MSG_NAMESPACE;
-
- X509CertificateCollection certificates;
-
- TaskCompletionSource authCompletion;
-
- public Dictionary notifications;
-
- public GcmXmppConnection (GcmXmppConfiguration configuration)
- {
- authCompletion = new TaskCompletionSource ();
-
- notifications = new Dictionary ();
- Configuration = configuration;
-
- certificates = new X509CertificateCollection ();
-
- // Add local/machine certificate stores to our collection if requested
- //if (Configuration.AddLocalAndMachineCertificateStores) {
- var store = new X509Store (StoreLocation.LocalMachine);
- certificates.AddRange (store.Certificates);
-
- store = new X509Store (StoreLocation.CurrentUser);
- certificates.AddRange (store.Certificates);
- //}
-
- // Add optionally specified additional certs into our collection
-// if (Configuration.AdditionalCertificates != null) {
-// foreach (var addlCert in Configuration.AdditionalCertificates)
-// certificates.Add (addlCert);
-// }
-
- // Finally, add the main private cert for authenticating to our collection
-// if (certificate != null)
-// certificates.Add (certificate);
- }
-
- public delegate void ReceiveMessageDelegate ();
- public event ReceiveMessageDelegate ReceiveMessage;
-
- public GcmXmppConfiguration Configuration { get; private set; }
-
- TcpClient client;
- SslStream sslStream;
- Stream stream;
-
- XmlWriter xml;
- bool exit = false;
- readonly object writeLock = new object ();
-
- public Task Connect ()
- {
- lock (writeLock) {
- client = new TcpClient ();
-
- Log.Debug ("GCM-XMPP: Connecting...");
-
- //await client.ConnectAsync (Configuration.Host, Configuration.Port).ConfigureAwait (false);
-
- client.Connect (Configuration.Host, Configuration.Port);
-
- Log.Debug ("GCM-XMPP: Connected. Creating Secure Channel...");
-
- sslStream = new SslStream (client.GetStream (), true, (sender, certificate, chain, sslPolicyErrors) => true);
-
- Log.Debug ("GCM-XMPP: Authenticating Tls...");
-
- sslStream.AuthenticateAsClient (Configuration.Host, certificates, System.Security.Authentication.SslProtocols.Tls, false);
- stream = sslStream;
-
- Log.Debug ("GCM-XMPP: Authenticated Tls.");
-
- var xws = new XmlWriterSettings {
- Async = true,
- OmitXmlDeclaration = true,
- Indent = true,
- NewLineHandling = NewLineHandling.None,
- Encoding = new UTF8Encoding (false),
- CloseOutput = false,
- };
-
- xml = XmlWriter.Create (stream, xws);
-
- Log.Debug ("GCM-XMPP: Writing opening element...");
-
- //Write initial stream:stream element
- xml.WriteStartElement (STREAM_PREFIX, STREAM_ELEMENT_NAME, STREAM_NAMESPACE);
- xml.WriteAttributeString (string.Empty, "to", string.Empty, "gcm.googleapis.com");
- xml.WriteAttributeString ("version", string.Format ("{0}.{1}", MAJOR_VERSION, MINOR_VERSION));
- xml.WriteAttributeString ("xmlns", JABBER_NAMESPACE);
- xml.WriteWhitespace ("\n");
- xml.Flush ();
-
- Log.Debug ("GCM-XMPP: Starting Listening...");
- }
-
- Task.Factory.StartNew (Listen);
-
- Log.Debug ("GCM-XMPP: Waiting for Authentication...");
- return authCompletion.Task;
- }
-
- public void Authenticate ()
- {
-// Auth Token
- Log.Debug ("GCM-XMPP: Authenticating...");
-
- XNamespace ns = SASL_NAMESPACE;
- var el = new XElement (ns + SASL_AUTH_ELEMENT_NAME, new XAttribute ("mechanism", "PLAIN"), Configuration.SaslAuthToken);
- WriteElement (el);
- }
-
- public void Send (CompletableNotification notification)
- {
-
- XNamespace ns = GCM_MSG_NAMESPACE;
- var gcm = new XElement (ns + "gcm", notification.Notification.ToJson ());
- var msg = new XElement ("message", new XAttribute ("id", string.Empty), gcm);
-
- Log.Debug ("GCM-XMPP: Sending: " + msg);
-
- try {
- WriteElement (msg);
-
- notifications.Add (notification.Notification.MessageId, notification);
- } catch (Exception ex) {
- notification.CompleteFailed (ex);
- }
- }
-
-
- void Listen()
- {
- try {
- var xrs = new XmlReaderSettings {
- //Async = true,
- CloseInput = false,
- ConformanceLevel = ConformanceLevel.Fragment,
-
- //IgnoreComments = true,
- //IgnoreWhitespace = true,
- // XmlResolver = null,
- };
-
- Log.Debug ("GCM-XMPP: Listening...");
-
- using (var xmlReader = XmlReader.Create (stream, xrs))
- {
- while (!exit && xmlReader.Read ()) //await xmlReader.ReadAsync ().ConfigureAwait (false))
- {
- Log.Debug ("GCM-XMPP: Read: " + xmlReader.NodeType + " - " + xmlReader.Name);
-
- if (xmlReader.NodeType == XmlNodeType.Element)
- {
- if (xmlReader.Name == STREAM_PREFIX + ":" + STREAM_ELEMENT_NAME) {
-
- Log.Debug ("GCM-XMPP: Stream initialization node received");
-
- } else {
- Log.Debug ("GCM-XMPP: Reading subtree...");
-
- var elem = XElement.Load (xmlReader.ReadSubtree ());
-
- Log.Debug ("GCM-XMPP: Loaded Subtree: " + elem);
-
- switch (elem.Name.LocalName)
- {
- case "success":
- authCompletion.TrySetResult (true);
- break;
- case "failed":
- authCompletion.TrySetResult (false);
- break;
- case "error":
-
- //TODO: Check for stanza error GCM
- Log.Debug ("XMPPStream error: " + elem.Value);
- break;
- case "features":
- Log.Debug ("Got Features");
- Authenticate ();
- break;
- case "message":
-
- //TODO: Received a message, let's parse it!
-
- var gcm = elem.Element (GCM_NS + "gcm");
-
- var err = elem.Element ("error");
-
- if (err != null) {
- //TODO: Handle stanza error
- } else {
- HandleMessage (gcm.Value);
- }
- break;
- default:
- break;
- }
-
- Log.Debug ("GCM-XMPP: Received: " + elem);
- }
-
- }
- else if (xmlReader.NodeType == XmlNodeType.EndElement && xmlReader.Name == STREAM_PREFIX + ":" + STREAM_ELEMENT_NAME)
- {
- Log.Debug ("GCM-XMPP: Server closed the stream");
- Close();
- break;
- } else {
- Log.Debug ("GCM-XMPP: WHAT?");
- }
-
-
-
-
-
- }
-
-
- }
- } catch (Exception ex) {
-
- Log.Error ("GCM-XMPP: Listener Error {0}", ex);
- authCompletion.TrySetResult (false);
- }
-
- // If there are any notifications we're waiting on, they need to be failed
- foreach (var n in notifications.Values)
- n.CompleteFailed (new Exception ("Connection Closed before response was received"));
-
- Log.Debug ("GCM-XMPP: Closed Listener");
- }
-
- public void Close ()
- {
- // exit = true;
-
- Log.Debug ("GCM-XMPP: Closing XMPP Stream");
- xml.WriteEndDocument ();
- xml.Flush ();
- }
-
- void WriteElement(XElement element)
- {
- lock (writeLock) {
- Log.Debug ("GCM-XMPP: Sending: " + element);
-
- element.WriteTo (xml);
- xml.Flush ();
- }
- }
-
-
- void HandleMessage (string json)
- {
- Log.Debug ("Incoming Message: " + json);
- }
-
- public class CompletableNotification
- {
- public CompletableNotification (GcmXmppNotification notification)
- {
- Notification = notification;
- completionSource = new TaskCompletionSource ();
- }
-
- public GcmXmppNotification Notification { get; private set; }
-
- readonly TaskCompletionSource completionSource;
-
- public async Task WaitForComplete ()
- {
- return await completionSource.Task.ConfigureAwait (false);
- }
-
- public void CompleteSuccessfully ()
- {
- completionSource.SetResult (null);
- }
-
- public void CompleteFailed (Exception ex)
- {
- completionSource.SetResult (ex);
- }
- }
-
- }
-}
-
diff --git a/PushSharp.Google/Xmpp/GcmXmppNotification.cs b/PushSharp.Google/Xmpp/GcmXmppNotification.cs
deleted file mode 100644
index 283fac3e..00000000
--- a/PushSharp.Google/Xmpp/GcmXmppNotification.cs
+++ /dev/null
@@ -1,119 +0,0 @@
-using System;
-using PushSharp.Core;
-using Newtonsoft.Json.Linq;
-using Newtonsoft.Json;
-
-namespace PushSharp.Google
-{
- public class GcmXmppNotification : INotification
- {
- public GcmXmppNotification ()
- {
- MessageId = "m-" + Guid.NewGuid ().ToString ("N");
- CollapseKey = string.Empty;
- Data = null;
- DelayWhileIdle = null;
- }
-
- public bool IsDeviceRegistrationIdValid ()
- {
- return !string.IsNullOrEmpty (To);
- }
-
- [JsonIgnore]
- public object Tag { get;set; }
-
- [JsonProperty ("message_id")]
- public string MessageId { get;set; }
-
- ///
- /// Registration ID or Group/Topic to send notification to. Overrides RegsitrationIds.
- ///
- /// To.
- [JsonProperty ("to")]
- public string To { get;set; }
-
- ///
- /// Only the latest message with the same collapse key will be delivered
- ///
- [JsonProperty ("collapse_key")]
- public string CollapseKey { get; set; }
-
- ///
- /// JSON Payload to be sent in the message
- ///
- [JsonProperty ("data")]
- public JObject Data { get; set; }
-
- ///
- /// Notification JSON payload
- ///
- /// The notification payload.
- [JsonProperty ("notification")]
- public JObject Notification { get; set; }
-
- [JsonProperty ("delivery_receipt_requested")]
- public bool? DeliveryReceiptRequested { get; set; }
-
- ///
- /// If true, GCM will only be delivered once the device's screen is on
- ///
- [JsonProperty ("delay_while_idle")]
- public bool? DelayWhileIdle { get; set; }
-
- ///
- /// Time in seconds that a message should be kept on the server if the device is offline. Default (and maximum) is 4 weeks.
- ///
- [JsonProperty ("time_to_live")]
- public int? TimeToLive { get; set; }
-
- ///
- /// If true, dry_run attribute will be sent in payload causing the notification not to be actually sent, but the result returned simulating the message
- ///
- [JsonProperty ("dry_run")]
- public bool? DryRun { get; set; }
-
- ///
- /// A string that maps a single user to multiple registration IDs associated with that user. This allows a 3rd-party server to send a single message to multiple app instances (typically on multiple devices) owned by a single user.
- ///
- [Obsolete ("Deprecated on GCM Server API. Use Device Group Messaging to send to multiple devices.")]
- public string NotificationKey { get; set; }
-
- ///
- /// A string containing the package name of your application. When set, messages will only be sent to registration IDs that match the package name
- ///
- [JsonProperty ("restricted_package_name")]
- public string RestrictedPackageName { get; set; }
-
- ///
- /// On iOS, use this field to represent content-available in the APNS payload. When a notification or message is sent and this is set to true, an inactive client app is awoken. On Android, data messages wake the app by default. On Chrome, currently not supported.
- ///
- /// The content available.
- [JsonProperty ("content_available")]
- public bool? ContentAvailable { get; set; }
-
- ///
- /// Corresponds to iOS APNS priorities (Normal is 5 and high is 10). Default is Normal.
- ///
- /// The priority.
- [JsonProperty ("priority")]
- public GcmNotificationPriority? Priority { get; set; }
-
- internal string GetJson ()
- {
- return JsonConvert.SerializeObject (this);
- }
-
- public override string ToString ()
- {
- return GetJson ();
- }
-
-
- public string ToJson ()
- {
- return JsonConvert.SerializeObject (this);
- }
- }
-}
-
diff --git a/PushSharp.Google/Xmpp/GcmXmppResponse.cs b/PushSharp.Google/Xmpp/GcmXmppResponse.cs
deleted file mode 100644
index d0d2b6a3..00000000
--- a/PushSharp.Google/Xmpp/GcmXmppResponse.cs
+++ /dev/null
@@ -1,93 +0,0 @@
-using System;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Converters;
-using System.Runtime.Serialization;
-
-namespace PushSharp.Google
-{
- public class GcmXmppResponse
- {
- public GcmXmppResponse ()
- {
- }
-
- [JsonProperty ("message_type", ItemConverterType = typeof (StringEnumConverter))]
- public ResponseMessageType MessageType { get;set; }
-
- [JsonProperty ("message_id")]
- public string MessageId { get;set; }
-
- [JsonProperty ("from")]
- public string From { get;set; }
-
- [JsonProperty ("error", ItemConverterType = typeof (StringEnumConverter))]
- public ResponseErrorType Error { get; set; }
-
- [JsonProperty ("error_description")]
- public string ErrorDescription { get; set; }
-
- }
-
- public enum ResponseMessageType
- {
- [EnumMember (Value="ack")]
- Ack,
-
- [EnumMember (Value="nack")]
- Nack,
-
- [EnumMember (Value="control")]
- Control
- }
-
- public enum ResponseErrorType
- {
- ///
- /// The ACK message is improperly formed.
- ///
- [EnumMember (Value="BAD_ACK")]
- BadAck,
-
- ///
- /// The device has a registration ID, but it's invalid or expired.
- ///
- [EnumMember (Value="BAD_REGISTRATION")]
- BadRegistration,
-
- ///
- /// The message couldn't be processed because the connection is draining. The message should be immediately retried over another connection.
- ///
- [EnumMember (Value="CONNECTION_DRAINING")]
- ConnectionDraining,
-
- ///
- /// The device is not registered.
- ///
- [EnumMember (Value="DEVICE_UNREGISTERED")]
- DeviceUnregistered,
-
- ///
- /// The server encountered an error while trying to process the request.
- ///
- [EnumMember (Value="INTERNAL_SERVER_ERROR")]
- InternalServerError,
-
- ///
- /// The JSON message payload is not valid.
- ///
- [EnumMember (Value="INVALID_JSON")]
- InvalidJson,
-
- ///
- /// The rate of messages to a particular registration ID (in other words, to a sender/device pair) is too high. If you want to retry the message, try using a slower rate.
- ///
- [EnumMember (Value="QUOTA_EXCEEDED")]
- QuotaExceeded,
-
- ///
- /// CCS is not currently able to process the message. The message should be r
- ///
- [EnumMember (Value="SERVICE_UNAVAILABLE")]
- ServiceUnavailable
- }
-}
diff --git a/PushSharp.Google/Xmpp/GcmXmppService.cs b/PushSharp.Google/Xmpp/GcmXmppService.cs
deleted file mode 100644
index 0e545ca8..00000000
--- a/PushSharp.Google/Xmpp/GcmXmppService.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-using System;
-using PushSharp.Core;
-using System.Threading.Tasks;
-
-namespace PushSharp.Google
-{
- public class GcmXmppServiceConnectionFactory : IServiceConnectionFactory
- {
- public GcmXmppServiceConnectionFactory (GcmXmppConfiguration configuration)
- {
- Configuration = configuration;
- }
-
- public GcmXmppConfiguration Configuration { get; private set; }
-
- public IServiceConnection Create()
- {
- return new GcmXmppServiceConnection (Configuration);
- }
- }
-
- public class GcmXmppServiceBroker : ServiceBroker
- {
- public GcmXmppServiceBroker (GcmXmppConfiguration configuration) : base (new GcmXmppServiceConnectionFactory (configuration))
- {
- }
- }
-
- public class GcmXmppServiceConnection : IServiceConnection
- {
- readonly GcmXmppConnection connection;
-
- public GcmXmppServiceConnection (GcmXmppConfiguration configuration)
- {
- connection = new GcmXmppConnection (configuration);
- }
-
- public async Task Send (GcmXmppNotification notification)
- {
- var completableNotification = new GcmXmppConnection.CompletableNotification (notification);
-
- connection.Send (completableNotification);
-
- var ex = await completableNotification.WaitForComplete ().ConfigureAwait (false);
-
- if (ex != null)
- throw ex;
- }
- }
-}
diff --git a/PushSharp.Google/packages.config b/PushSharp.Google/packages.config
deleted file mode 100644
index 505e5883..00000000
--- a/PushSharp.Google/packages.config
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/PushSharp.Tests/AdmRealTests.cs b/PushSharp.Tests/AdmRealTests.cs
index 4c17e4c8..87fa0ec3 100644
--- a/PushSharp.Tests/AdmRealTests.cs
+++ b/PushSharp.Tests/AdmRealTests.cs
@@ -1,7 +1,7 @@
using System;
using NUnit.Framework;
-using PushSharp.Amazon;
using System.Collections.Generic;
+using PushSharp.Amazon;
namespace PushSharp.Tests
{
diff --git a/PushSharp.Tests/ApnsHttp2RealTests.cs b/PushSharp.Tests/ApnsHttp2RealTests.cs
deleted file mode 100644
index 80b249ac..00000000
--- a/PushSharp.Tests/ApnsHttp2RealTests.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-using System;
-using NUnit.Framework;
-using PushSharp.Apple;
-using Newtonsoft.Json.Linq;
-
-namespace PushSharp.Tests
-{
- [TestFixture]
- [Category("Disabled")]
- public class ApnsHttp2RealTests
- {
- [Test]
- public void APNSHTTP2_Send_Single()
- {
- var succeeded = 0;
- var failed = 0;
- var attempted = 0;
-
- var config = new ApnsHttp2Configuration(ApnsHttp2Configuration.ApnsServerEnvironment.Sandbox, Settings.Instance.ApnsCertificateFile, Settings.Instance.ApnsCertificatePassword);
- var broker = new ApnsHttp2ServiceBroker(config);
- broker.OnNotificationFailed += (notification, exception) => {
- failed++;
- };
- broker.OnNotificationSucceeded += (notification) => {
- succeeded++;
- };
- broker.Start();
-
- foreach (var dt in Settings.Instance.ApnsDeviceTokens)
- {
- attempted++;
- broker.QueueNotification(new ApnsHttp2Notification
- {
- DeviceToken = dt,
- Topic = "com.pushsharp.sample",
- Payload = JObject.Parse("{ \"aps\" : { \"alert\" : \"Hello PushSharp!\", \"badge\" : 5, \"sound\" : \"blank.aiff\" } }")
- });
- }
-
- broker.Stop();
-
- Assert.AreEqual(attempted, succeeded);
- Assert.AreEqual(0, failed);
- }
- }
-}
-
diff --git a/PushSharp.Tests/ApnsTests.cs b/PushSharp.Tests/ApnsTests.cs
index b7e5ab3f..0ab37046 100644
--- a/PushSharp.Tests/ApnsTests.cs
+++ b/PushSharp.Tests/ApnsTests.cs
@@ -5,7 +5,8 @@
using System.Threading;
using Newtonsoft.Json.Linq;
using NUnit.Framework;
-using PushSharp.Core;
+using PushSharp.Common;
+using PushSharp.Tests.Servers;
namespace PushSharp.Tests
{
diff --git a/PushSharp.Tests/BrokerTests.cs b/PushSharp.Tests/BrokerTests.cs
index 92308707..ed3f6fef 100644
--- a/PushSharp.Tests/BrokerTests.cs
+++ b/PushSharp.Tests/BrokerTests.cs
@@ -1,13 +1,13 @@
using NUnit.Framework;
using System;
-using PushSharp.Core;
using System.Threading.Tasks;
using System.Linq;
using System.Collections.Generic;
using PushSharp.Apple;
using Newtonsoft.Json.Linq;
using System.Threading;
+using PushSharp.Common;
namespace PushSharp.Tests
diff --git a/PushSharp.Tests/GcmXmppTests.cs b/PushSharp.Tests/GcmXmppTests.cs
deleted file mode 100644
index 4adf6795..00000000
--- a/PushSharp.Tests/GcmXmppTests.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-using System;
-using NUnit.Framework;
-using System.Threading.Tasks;
-using PushSharp.Google;
-using PushSharp.Core;
-using System.Collections.Generic;
-using Newtonsoft.Json.Linq;
-
-namespace PushSharp.Tests
-{
- [TestFixture]
- [Category ("Disabled")]
- public class GcmXmppTests
- {
- [Test]
- public async Task GCMXMPP_Connect ()
- {
- var succeeded = 0;
- var failed = 0;
- var attempted = 0;
-
- var c = new GcmXmppConfiguration {
- Production = false,
- AuthenticationToken = Settings.Instance.GcmAuthToken,
- SenderIDs = new List { Settings.Instance.GcmSenderId }
- };
-
- var gcm = new GcmXmppConnection (c);
- await gcm.Connect ();
-
- foreach (var regId in Settings.Instance.GcmRegistrationIds) {
- gcm.Send (new GcmXmppConnection.CompletableNotification (new GcmXmppNotification {
- To = regId,
- Data = JObject.Parse ("{ \"somekey\" : \"somevalue\" }")
- }));
- }
-
- gcm.Close ();
-
- Assert.AreEqual (attempted, succeeded);
- Assert.AreEqual (0, failed);
- }
- }
-}
-
diff --git a/PushSharp.Tests/PushSharp.Tests.csproj b/PushSharp.Tests/PushSharp.Tests.csproj
index 6cdef5f4..e958cf0f 100644
--- a/PushSharp.Tests/PushSharp.Tests.csproj
+++ b/PushSharp.Tests/PushSharp.Tests.csproj
@@ -1,84 +1,22 @@
-
-
+
+
- Debug
- AnyCPU
- {989B7357-800E-46B9-91AF-A4CE8A55F389}
- Library
- PushSharp.Tests
- PushSharp.Tests
- v4.5
+ netstandard2.0;net45;
-
- true
- full
- false
- bin\Debug
- DEBUG;
- prompt
- 4
- false
-
-
- full
- true
- bin\Release
- prompt
- 4
- false
-
-
-
-
- ..\packages\NUnit.2.6.4\lib\nunit.framework.dll
-
-
- ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {2B44A8DA-60BC-4577-A2D7-D9D53F164B2E}
- PushSharp.Core
-
-
- {A9D99F80-FEEB-4E74-96C5-66F17103C773}
- PushSharp.Apple
-
-
- {2468C63B-C964-4FC3-9B16-13DC17CF7D11}
- PushSharp.Amazon
-
-
- {94F16497-471F-433F-A99E-C455FB2D7724}
- PushSharp.Google
-
-
- {DC80552B-6730-44AA-9B74-1E036BD909C3}
- PushSharp.Windows
-
-
+
-
-
+
+
-
+
-
+
+
+
+
+
+
+
-
\ No newline at end of file
+
+
diff --git a/PushSharp.Tests/Servers/TestApnsServer.cs b/PushSharp.Tests/Servers/TestApnsServer.cs
index 1be38243..8c086d54 100644
--- a/PushSharp.Tests/Servers/TestApnsServer.cs
+++ b/PushSharp.Tests/Servers/TestApnsServer.cs
@@ -1,11 +1,11 @@
using System;
-using System.Threading.Tasks;
-using System.Net.Sockets;
-using System.Net;
using System.Collections.Generic;
+using System.Net;
+using System.Net.Sockets;
using System.Threading;
+using System.Threading.Tasks;
-namespace PushSharp.Tests
+namespace PushSharp.Tests.Servers
{
public class TestApnsServer
{
diff --git a/PushSharp.Tests/TestServiceConnection.cs b/PushSharp.Tests/TestServiceConnection.cs
index 628dac9c..4ac3a0fd 100644
--- a/PushSharp.Tests/TestServiceConnection.cs
+++ b/PushSharp.Tests/TestServiceConnection.cs
@@ -1,7 +1,7 @@
using System;
using System.Linq;
-using PushSharp.Core;
using System.Threading.Tasks;
+using PushSharp.Common;
namespace PushSharp.Tests
{
diff --git a/PushSharp.Tests/apns-com.pushsharp.sample.p12 b/PushSharp.Tests/apns-com.pushsharp.sample.p12
deleted file mode 100644
index 49e2c9b3..00000000
Binary files a/PushSharp.Tests/apns-com.pushsharp.sample.p12 and /dev/null differ
diff --git a/PushSharp.Tests/packages.config b/PushSharp.Tests/packages.config
deleted file mode 100644
index 3b829b9f..00000000
--- a/PushSharp.Tests/packages.config
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/PushSharp.Tests/settings.sample.json b/PushSharp.Tests/settings.sample.json
deleted file mode 100644
index b4994bbe..00000000
--- a/PushSharp.Tests/settings.sample.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "apns_cert_file" : "",
- "apns_cert_pwd" : "",
- "apns_device_tokens" :
- [
- "",
- ],
-
- "gcm_auth_token" : "",
- "gcm_sender_id" : "",
- "gcm_registration_ids" :
- [
- "",
- ],
-
- "adm_client_id" : "",
- "adm_client_secret" : "",
- "adm_registration_ids" :
- [
- "",
- ],
-}
diff --git a/PushSharp.Windows/Exceptions.cs b/PushSharp.Windows/Exceptions.cs
index d3d39ded..284984ae 100644
--- a/PushSharp.Windows/Exceptions.cs
+++ b/PushSharp.Windows/Exceptions.cs
@@ -1,5 +1,5 @@
using System;
-using PushSharp.Core;
+using PushSharp.Common;
namespace PushSharp.Windows
{
diff --git a/PushSharp.Windows/Properties/AssemblyInfo.cs b/PushSharp.Windows/Properties/AssemblyInfo.cs
deleted file mode 100644
index 61efcba9..00000000
--- a/PushSharp.Windows/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
-
-[assembly: AssemblyTitle ("PushSharp.Windows")]
-[assembly: AssemblyDescription ("")]
-[assembly: AssemblyConfiguration ("")]
-[assembly: AssemblyCompany ("")]
-[assembly: AssemblyProduct ("")]
-[assembly: AssemblyCopyright ("redth")]
-[assembly: AssemblyTrademark ("")]
-[assembly: AssemblyCulture ("")]
-
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
-
-[assembly: AssemblyVersion ("1.0.*")]
-
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
-
diff --git a/PushSharp.Windows/PushSharp.Windows.csproj b/PushSharp.Windows/PushSharp.Windows.csproj
index e85dc90b..423e97be 100644
--- a/PushSharp.Windows/PushSharp.Windows.csproj
+++ b/PushSharp.Windows/PushSharp.Windows.csproj
@@ -1,60 +1,19 @@
-
-
+
+
- Debug
- AnyCPU
- {DC80552B-6730-44AA-9B74-1E036BD909C3}
- Library
- PushSharp.Windows
- PushSharp.Windows
- v4.5
- true
- ..\PushSharp-Signing.snk
-
-
- true
- full
- false
- bin\Debug
- DEBUG;
- prompt
- 4
- false
-
-
- full
- true
- bin\Release
- prompt
- 4
- false
+ netstandard2.0;net45;
+
-
-
-
-
-
- ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll
-
+
-
-
-
-
-
-
-
-
-
-
-
-
- {2B44A8DA-60BC-4577-A2D7-D9D53F164B2E}
- PushSharp.Core
-
+
+
+
+
-
+
-
\ No newline at end of file
+
+
diff --git a/PushSharp.Windows/WnsConnection.cs b/PushSharp.Windows/WnsConnection.cs
index 6ab72c43..b4328b5c 100644
--- a/PushSharp.Windows/WnsConnection.cs
+++ b/PushSharp.Windows/WnsConnection.cs
@@ -1,5 +1,4 @@
using System;
-using PushSharp.Core;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net.Http.Headers;
@@ -10,6 +9,7 @@
using System.Net;
using System.Text;
using System.IO;
+using PushSharp.Common;
namespace PushSharp.Windows
{
diff --git a/PushSharp.Windows/WnsNotification.cs b/PushSharp.Windows/WnsNotification.cs
index a8a16dca..9b6e1bf9 100644
--- a/PushSharp.Windows/WnsNotification.cs
+++ b/PushSharp.Windows/WnsNotification.cs
@@ -1,5 +1,5 @@
-using PushSharp.Core;
-using System.Xml.Linq;
+using System.Xml.Linq;
+using PushSharp.Common;
namespace PushSharp.Windows
{
diff --git a/PushSharp.Windows/WnsTokenAccessManager.cs b/PushSharp.Windows/WnsTokenAccessManager.cs
index 8e2c9908..92d4346e 100644
--- a/PushSharp.Windows/WnsTokenAccessManager.cs
+++ b/PushSharp.Windows/WnsTokenAccessManager.cs
@@ -1,9 +1,9 @@
using System;
using System.Threading.Tasks;
using System.Net.Http;
-using PushSharp.Core;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
+using PushSharp.Common;
namespace PushSharp.Windows
{
diff --git a/PushSharp.Windows/packages.config b/PushSharp.Windows/packages.config
deleted file mode 100644
index 505e5883..00000000
--- a/PushSharp.Windows/packages.config
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/PushSharp.nuspec b/PushSharp.nuspec
index ab2b8a80..28f3c692 100644
--- a/PushSharp.nuspec
+++ b/PushSharp.nuspec
@@ -1,37 +1,41 @@
- PushSharp
- $version$
- PushSharp
- Redth
- Redth
+ PushSharp.Core
+ 1.0.0
+ PushSharp.Core
+ Redth, mitch-tofi
+ Redth, mitch-tofi
http://www.apache.org/licenses/LICENSE-2.0.txt
- https://github.com/Redth/PushSharp/
- https://github.com/Redth/PushSharp/raw/master/Resources/PushSharp-Icon-NuGet-Small.png
+ https://github.com/mitch-tofi/PushSharp.Core
+ https://github.com/mitch-tofi/PushSharp.Core/raw/master/Resources/PushSharp-Icon-NuGet-Small.png
false
A server-side library for sending Push Notifications to iOS/OSX (APNS), Android/Chrome (GCM), Windows Phone/Windows (WNS), Amazon (ADM), Blackberry and Firefox OS
A server-side library for sending Push Notifications to many platforms (APNS, GCM, WNS, ADM)
- 3.0.0 - Complete Rewrite, New API, see project site for more info
+ 1.0.0 - Forked from PushSharp and added support NetStandard 2.0
- 2012-2016 Redth
+ 2012-2017 Redth, mitch-tofi
en-US
APN, APNS, GCM, XMPP, ADM, GCMXMPP, C2DM, PAP, BIS, BEM, Blackberry, iOS, Android, iPad, iPhone, PushSharp, MDM, UWP, WNS, Windows Notification, Amazon, Amazon Device, Push, Push Notifications, Google Cloud, Cloud Messaging, Google Cloud Messaging, OSX, Mac, WindowsPhone, PassKit
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PushSharp.sln b/PushSharp.sln
deleted file mode 100644
index d96c467d..00000000
--- a/PushSharp.sln
+++ /dev/null
@@ -1,71 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2012
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PushSharp.Core", "PushSharp.Core\PushSharp.Core.csproj", "{2B44A8DA-60BC-4577-A2D7-D9D53F164B2E}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PushSharp.Tests", "PushSharp.Tests\PushSharp.Tests.csproj", "{989B7357-800E-46B9-91AF-A4CE8A55F389}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Platforms", "Platforms", "{2B7243CB-60A5-4682-802B-B7EC3DEBCF9A}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PushSharp.Apple", "PushSharp.Apple\PushSharp.Apple.csproj", "{A9D99F80-FEEB-4E74-96C5-66F17103C773}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PushSharp.Windows", "PushSharp.Windows\PushSharp.Windows.csproj", "{DC80552B-6730-44AA-9B74-1E036BD909C3}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PushSharp.Firefox", "PushSharp.Firefox\PushSharp.Firefox.csproj", "{54A4C1F9-6571-4086-BB4B-EC202138AF00}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PushSharp.Amazon", "PushSharp.Amazon\PushSharp.Amazon.csproj", "{2468C63B-C964-4FC3-9B16-13DC17CF7D11}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PushSharp.Google", "PushSharp.Google\PushSharp.Google.csproj", "{94F16497-471F-433F-A99E-C455FB2D7724}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PushSharp.Blackberry", "PushSharp.Blackberry\PushSharp.Blackberry.csproj", "{9F972AE9-DE47-4C26-AEE0-97E8A14F2E12}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Support Libraries", "Support Libraries", "{6449DAB1-E76A-4354-B633-CC6AC53BB757}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {2468C63B-C964-4FC3-9B16-13DC17CF7D11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {2468C63B-C964-4FC3-9B16-13DC17CF7D11}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {2468C63B-C964-4FC3-9B16-13DC17CF7D11}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {2468C63B-C964-4FC3-9B16-13DC17CF7D11}.Release|Any CPU.Build.0 = Release|Any CPU
- {2B44A8DA-60BC-4577-A2D7-D9D53F164B2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {2B44A8DA-60BC-4577-A2D7-D9D53F164B2E}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {2B44A8DA-60BC-4577-A2D7-D9D53F164B2E}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {2B44A8DA-60BC-4577-A2D7-D9D53F164B2E}.Release|Any CPU.Build.0 = Release|Any CPU
- {54A4C1F9-6571-4086-BB4B-EC202138AF00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {54A4C1F9-6571-4086-BB4B-EC202138AF00}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {54A4C1F9-6571-4086-BB4B-EC202138AF00}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {54A4C1F9-6571-4086-BB4B-EC202138AF00}.Release|Any CPU.Build.0 = Release|Any CPU
- {94F16497-471F-433F-A99E-C455FB2D7724}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {94F16497-471F-433F-A99E-C455FB2D7724}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {94F16497-471F-433F-A99E-C455FB2D7724}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {94F16497-471F-433F-A99E-C455FB2D7724}.Release|Any CPU.Build.0 = Release|Any CPU
- {989B7357-800E-46B9-91AF-A4CE8A55F389}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {989B7357-800E-46B9-91AF-A4CE8A55F389}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {989B7357-800E-46B9-91AF-A4CE8A55F389}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {989B7357-800E-46B9-91AF-A4CE8A55F389}.Release|Any CPU.Build.0 = Release|Any CPU
- {9F972AE9-DE47-4C26-AEE0-97E8A14F2E12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {9F972AE9-DE47-4C26-AEE0-97E8A14F2E12}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {9F972AE9-DE47-4C26-AEE0-97E8A14F2E12}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {9F972AE9-DE47-4C26-AEE0-97E8A14F2E12}.Release|Any CPU.Build.0 = Release|Any CPU
- {A9D99F80-FEEB-4E74-96C5-66F17103C773}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A9D99F80-FEEB-4E74-96C5-66F17103C773}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {A9D99F80-FEEB-4E74-96C5-66F17103C773}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A9D99F80-FEEB-4E74-96C5-66F17103C773}.Release|Any CPU.Build.0 = Release|Any CPU
- {DC80552B-6730-44AA-9B74-1E036BD909C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {DC80552B-6730-44AA-9B74-1E036BD909C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {DC80552B-6730-44AA-9B74-1E036BD909C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {DC80552B-6730-44AA-9B74-1E036BD909C3}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {A9D99F80-FEEB-4E74-96C5-66F17103C773} = {2B7243CB-60A5-4682-802B-B7EC3DEBCF9A}
- {DC80552B-6730-44AA-9B74-1E036BD909C3} = {2B7243CB-60A5-4682-802B-B7EC3DEBCF9A}
- {54A4C1F9-6571-4086-BB4B-EC202138AF00} = {2B7243CB-60A5-4682-802B-B7EC3DEBCF9A}
- {2468C63B-C964-4FC3-9B16-13DC17CF7D11} = {2B7243CB-60A5-4682-802B-B7EC3DEBCF9A}
- {94F16497-471F-433F-A99E-C455FB2D7724} = {2B7243CB-60A5-4682-802B-B7EC3DEBCF9A}
- {9F972AE9-DE47-4C26-AEE0-97E8A14F2E12} = {2B7243CB-60A5-4682-802B-B7EC3DEBCF9A}
- EndGlobalSection
-EndGlobal
diff --git a/README.md b/README.md
index b3ae1f9b..d77d1179 100644
--- a/README.md
+++ b/README.md
@@ -150,7 +150,7 @@ gcmBroker.OnNotificationFailed += (notification, aggregateEx) => {
Console.WriteLine ($"Device RegistrationId Expired: {oldId}");
- if (!string.IsNullOrWhitespace (newId)) {
+ if (!string.IsNullOrWhiteSpace (newId)) {
// If this value isn't null, our subscription changed and we should update our database
Console.WriteLine ($"Device RegistrationId Changed To: {newId}");
}
@@ -252,6 +252,25 @@ foreach (var uri in MY_DEVICE_CHANNEL_URIS) {
wnsBroker.Stop ();
```
+### Use a Proxy with APNS or GCM
+
+To configure a proxy call `SetProxy` method on the appropriate configuration object.
+
+```csharp
+// create ApnsConfiguration or GcmConfiguration as needed
+var config = new ApnsConfiguration (ApnsConfiguration.ApnsServerEnvironment.Sandbox,
+ "push-cert.p12", "push-cert-pwd");
+
+// set up a proxy
+if (useProxy)
+{
+ config.SetProxy(proxyAddress, proxyPort);
+}
+
+// continue as in the examples above
+// ...
+```
+
## How to Migrate from PushSharp 2.x to 3.x and higher