ApnsFeedbackConnection.java 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /*
  2. * Copyright 2009, Mahmood Ali.
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are
  7. * met:
  8. *
  9. * * Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * * Redistributions in binary form must reproduce the above
  12. * copyright notice, this list of conditions and the following disclaimer
  13. * in the documentation and/or other materials provided with the
  14. * distribution.
  15. * * Neither the name of Mahmood Ali. nor the names of its
  16. * contributors may be used to endorse or promote products derived from
  17. * this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. package com.notnoop.apns.internal;
  32. import java.io.IOException;
  33. import java.io.InputStream;
  34. import java.net.InetSocketAddress;
  35. import java.net.Proxy;
  36. import java.net.Socket;
  37. import java.util.Date;
  38. import java.util.Map;
  39. import javax.net.SocketFactory;
  40. import javax.net.ssl.SSLSocketFactory;
  41. import org.slf4j.Logger;
  42. import org.slf4j.LoggerFactory;
  43. import com.notnoop.exceptions.NetworkIOException;
  44. public class ApnsFeedbackConnection {
  45. private static final Logger logger = LoggerFactory.getLogger(ApnsFeedbackConnection.class);
  46. private final SocketFactory factory;
  47. private final String host;
  48. private final int port;
  49. private final Proxy proxy;
  50. private final int readTimeout;
  51. private final int connectTimeout;
  52. private final String proxyUsername;
  53. private final String proxyPassword;
  54. public ApnsFeedbackConnection(final SocketFactory factory, final String host, final int port) {
  55. this(factory, host, port, null, 0, 0, null, null);
  56. }
  57. public ApnsFeedbackConnection(final SocketFactory factory, final String host, final int port,
  58. final Proxy proxy, int readTimeout, int connectTimeout, final String proxyUsername, final String proxyPassword) {
  59. this.factory = factory;
  60. this.host = host;
  61. this.port = port;
  62. this.proxy = proxy;
  63. this.readTimeout = readTimeout;
  64. this.connectTimeout = connectTimeout;
  65. this.proxyUsername = proxyUsername;
  66. this.proxyPassword = proxyPassword;
  67. }
  68. int DELAY_IN_MS = 1000;
  69. private static final int RETRIES = 3;
  70. public Map<String, Date> getInactiveDevices() throws NetworkIOException {
  71. int attempts = 0;
  72. while (true) {
  73. try {
  74. attempts++;
  75. final Map<String, Date> result = getInactiveDevicesImpl();
  76. attempts = 0;
  77. return result;
  78. } catch (final Exception e) {
  79. logger.warn("Failed to retrieve invalid devices", e);
  80. if (attempts >= RETRIES) {
  81. logger.error("Couldn't get feedback connection", e);
  82. Utilities.wrapAndThrowAsRuntimeException(e);
  83. }
  84. Utilities.sleep(DELAY_IN_MS);
  85. }
  86. }
  87. }
  88. public Map<String, Date> getInactiveDevicesImpl() throws IOException {
  89. Socket proxySocket = null;
  90. Socket socket = null;
  91. try {
  92. if (proxy == null) {
  93. socket = factory.createSocket(host, port);
  94. } else if (proxy.type() == Proxy.Type.HTTP) {
  95. TlsTunnelBuilder tunnelBuilder = new TlsTunnelBuilder();
  96. socket = tunnelBuilder.build((SSLSocketFactory) factory, proxy, proxyUsername, proxyPassword, host, port);
  97. } else {
  98. proxySocket = new Socket(proxy);
  99. proxySocket.connect(new InetSocketAddress(host, port), connectTimeout);
  100. socket = ((SSLSocketFactory) factory).createSocket(proxySocket, host, port, false);
  101. }
  102. socket.setSoTimeout(readTimeout);
  103. socket.setKeepAlive(true);
  104. final InputStream stream = socket.getInputStream();
  105. return Utilities.parseFeedbackStream(stream);
  106. } finally {
  107. Utilities.close(socket);
  108. Utilities.close(proxySocket);
  109. }
  110. }
  111. }