From 99444ef211cb3522f8d015731b6b708321ce1f5b Mon Sep 17 00:00:00 2001 From: kamhung <22250530@qq.com> Date: Wed, 9 Dec 2015 10:30:21 +0800 Subject: [PATCH] --- .../redkale/net/socks/NodeSocksServer.java | 67 ---- .../net/socks/SocksConnectServlet.java | 56 ---- .../net/socks/SocksPrepareServlet.java | 45 --- .../redkale/net/socks/SocksProxyServlet.java | 197 ----------- .../redkale/net/socks/SocksRequest.java | 87 ----- .../redkale/net/socks/SocksResponse.java | 32 -- .../wentch/redkale/net/socks/SocksRunner.java | 223 ------------ .../wentch/redkale/net/socks/SocksServer.java | 59 ---- .../redkale/net/socks/SocksServlet.java | 28 -- .../redkale/service/apns/ApnsMessage.java | 93 ----- .../redkale/service/apns/ApnsPayload.java | 247 -------------- .../redkale/service/apns/ApnsService.java | 161 --------- .../service/weixin/WeiXinMPService.java | 103 ------ .../service/weixin/WeiXinPayResult.java | 77 ----- .../service/weixin/WeiXinPayService.java | 256 -------------- .../service/weixin/WeiXinQYMessage.java | 117 ------- .../service/weixin/WeiXinQYService.java | 317 ------------------ 17 files changed, 2165 deletions(-) delete mode 100644 src-plugin/com/wentch/redkale/net/socks/NodeSocksServer.java delete mode 100644 src-plugin/com/wentch/redkale/net/socks/SocksConnectServlet.java delete mode 100644 src-plugin/com/wentch/redkale/net/socks/SocksPrepareServlet.java delete mode 100644 src-plugin/com/wentch/redkale/net/socks/SocksProxyServlet.java delete mode 100644 src-plugin/com/wentch/redkale/net/socks/SocksRequest.java delete mode 100644 src-plugin/com/wentch/redkale/net/socks/SocksResponse.java delete mode 100644 src-plugin/com/wentch/redkale/net/socks/SocksRunner.java delete mode 100644 src-plugin/com/wentch/redkale/net/socks/SocksServer.java delete mode 100644 src-plugin/com/wentch/redkale/net/socks/SocksServlet.java delete mode 100644 src-plugin/com/wentch/redkale/service/apns/ApnsMessage.java delete mode 100644 src-plugin/com/wentch/redkale/service/apns/ApnsPayload.java delete mode 100644 src-plugin/com/wentch/redkale/service/apns/ApnsService.java delete mode 100644 src-plugin/com/wentch/redkale/service/weixin/WeiXinMPService.java delete mode 100644 src-plugin/com/wentch/redkale/service/weixin/WeiXinPayResult.java delete mode 100644 src-plugin/com/wentch/redkale/service/weixin/WeiXinPayService.java delete mode 100644 src-plugin/com/wentch/redkale/service/weixin/WeiXinQYMessage.java delete mode 100644 src-plugin/com/wentch/redkale/service/weixin/WeiXinQYService.java diff --git a/src-plugin/com/wentch/redkale/net/socks/NodeSocksServer.java b/src-plugin/com/wentch/redkale/net/socks/NodeSocksServer.java deleted file mode 100644 index 0b65340e6..000000000 --- a/src-plugin/com/wentch/redkale/net/socks/NodeSocksServer.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.wentch.redkale.net.socks; - -import com.wentch.redkale.boot.ClassFilter.FilterEntry; -import com.wentch.redkale.boot.*; -import static com.wentch.redkale.boot.NodeServer.LINE_SEPARATOR; -import com.wentch.redkale.net.*; -import com.wentch.redkale.util.*; -import com.wentch.redkale.util.AnyValue.DefaultAnyValue; -import java.lang.reflect.*; -import java.net.*; -import java.util.logging.*; - -/** - * < server protocol="SOCKS" host="0.0.0.0" port="1080" bindaddr="外网IP"> < /server> - * - * @author zhangjx - */ -@NodeProtocol({"SOCKS"}) -public class NodeSocksServer extends NodeServer { - - private final SocksServer socksServer; - - public NodeSocksServer(Application application, AnyValue serconf) { - super(application, application.getResourceFactory().createChild(), createServer(application, serconf)); - this.socksServer = (SocksServer) server; - } - - private static Server createServer(Application application, AnyValue serconf) { - return new SocksServer(application.getStartTime(), application.getWatchFactory()); - } - - @Override - public InetSocketAddress getSocketAddress() { - return socksServer == null ? null : socksServer.getSocketAddress(); - } - - @Override - protected ClassFilter createServletClassFilter() { - return createClassFilter(null, null, SocksServlet.class, null, "servlets", "servlet"); - } - - @Override - protected void loadServlet(ClassFilter servletFilter) throws Exception { - if (socksServer != null) loadSocksServlet(this.nodeConf.getAnyValue("servlets"), servletFilter); - } - - protected void loadSocksServlet(final AnyValue conf, ClassFilter filter) throws Exception { - final StringBuilder sb = logger.isLoggable(Level.FINE) ? new StringBuilder() : null; - final String threadName = "[" + Thread.currentThread().getName() + "] "; - for (FilterEntry en : filter.getFilterEntrys()) { - Class clazz = (Class) en.getType(); - if (Modifier.isAbstract(clazz.getModifiers())) continue; - final SocksServlet servlet = clazz.newInstance(); - factory.inject(servlet); - DefaultAnyValue servletConf = (DefaultAnyValue) en.getProperty(); - this.socksServer.addSocksServlet(servlet, servletConf); - if (sb != null) sb.append(threadName).append(" Loaded ").append(clazz.getName()).append(" --> ").append(servletConf).append(LINE_SEPARATOR); - } - if (sb != null && sb.length() > 0) logger.log(Level.FINE, sb.toString()); - } - -} diff --git a/src-plugin/com/wentch/redkale/net/socks/SocksConnectServlet.java b/src-plugin/com/wentch/redkale/net/socks/SocksConnectServlet.java deleted file mode 100644 index 2cd5af0c9..000000000 --- a/src-plugin/com/wentch/redkale/net/socks/SocksConnectServlet.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.wentch.redkale.net.socks; - -import com.wentch.redkale.net.*; -import com.wentch.redkale.util.*; -import java.io.*; -import java.net.*; -import java.nio.*; -import java.util.logging.*; - -/** - * - * @author zhangjx - */ -@AutoLoad(false) -public class SocksConnectServlet extends SocksServlet { - - private InetSocketAddress bindAddress; - - private byte[] bindAddressBytes = new byte[0]; - - @Override - public void init(Context context, AnyValue config) { - if (config == null) { - this.bindAddress = new InetSocketAddress(Utility.localInetAddress(), context.getServerAddress().getPort()); - } else { - this.bindAddress = new InetSocketAddress(config.getValue("bindaddr", Utility.localInetAddress().getHostAddress()), context.getServerAddress().getPort()); - } - Logger logger = context.getLogger(); - if (logger.isLoggable(Level.INFO)) logger.info("[" + Thread.currentThread().getName() + "] bindAddress = " + bindAddress); - ByteBuffer bb; - InetAddress addr = bindAddress.getAddress(); - if (addr instanceof Inet6Address) { - bb = ByteBuffer.allocate(1 + 16 + 2); - bb.put((byte) 0x04); - } else { - bb = ByteBuffer.allocate(1 + 4 + 2); - bb.put((byte) 0x01); - } - bb.put(addr.getAddress()); - bb.putChar((char) bindAddress.getPort()); - bb.flip(); - this.bindAddressBytes = bb.array(); - } - - @Override - public void execute(SocksRequest request, SocksResponse response) throws IOException { - response.getContext().submit(new SocksRunner(response.getContext(), response.removeChannel(), bindAddressBytes)); - response.finish(true); - } - -} diff --git a/src-plugin/com/wentch/redkale/net/socks/SocksPrepareServlet.java b/src-plugin/com/wentch/redkale/net/socks/SocksPrepareServlet.java deleted file mode 100644 index 90bc0bd8b..000000000 --- a/src-plugin/com/wentch/redkale/net/socks/SocksPrepareServlet.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.wentch.redkale.net.socks; - -import com.wentch.redkale.net.*; -import com.wentch.redkale.util.*; -import java.io.*; - -/** - * - * @author zhangjx - */ -public final class SocksPrepareServlet extends PrepareServlet { - - private SocksServlet socksServlet = new SocksConnectServlet(); - - private SocksProxyServlet proxyServlet = new SocksProxyServlet(); - - public SocksPrepareServlet() { - } - - @Override - public void init(Context context, AnyValue config) { - if (socksServlet != null) socksServlet.init(context, socksServlet.conf == null ? config : socksServlet.conf); - } - - public void setSocksServlet(SocksServlet servlet, AnyValue conf) { - servlet.conf = conf; - if (servlet != null) this.socksServlet = servlet; - } - - // - @Override - public void execute(SocksRequest request, SocksResponse response) throws IOException { - if (request.isHttp()) { - proxyServlet.execute(request, response); - } else { - socksServlet.execute(request, response); - } - } - -} diff --git a/src-plugin/com/wentch/redkale/net/socks/SocksProxyServlet.java b/src-plugin/com/wentch/redkale/net/socks/SocksProxyServlet.java deleted file mode 100644 index f8be74ae7..000000000 --- a/src-plugin/com/wentch/redkale/net/socks/SocksProxyServlet.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.wentch.redkale.net.socks; - -import com.wentch.redkale.net.*; -import com.wentch.redkale.util.*; -import java.io.*; -import java.net.*; -import java.nio.*; -import java.nio.channels.*; - -/** - * 正向代理 - * - * @author zhangjx - */ -@AutoLoad(false) -public final class SocksProxyServlet extends SocksServlet { - - protected static final byte[] LINE = new byte[]{'\r', '\n'}; - - @Override - public void execute(SocksRequest request, SocksResponse response) throws IOException { - response.skipHeader(); - if ("CONNECT".equalsIgnoreCase(request.getMethod())) { - connect(request, response); - return; - } - String url = request.getRequestURI(); - url = url.substring(url.indexOf("://") + 3); - url = url.substring(url.indexOf('/')); - final ByteBuffer buffer = response.getContext().pollBuffer(); - buffer.put((request.getMethod() + " " + url + " HTTP/1.1\r\n").getBytes()); - for (String header : request.getHeaderNames()) { - if (!header.startsWith("Proxy-")) { - buffer.put((header + ": " + request.getHeader(header) + "\r\n").getBytes()); - } - } - if (request.getHost() != null) { - buffer.put(("Host: " + request.getHost() + "\r\n").getBytes()); - } - if (request.getContentType() != null) { - buffer.put(("Content-Type: " + request.getContentType() + "\r\n").getBytes()); - } - if (request.getContentLength() > 0) { - buffer.put(("Content-Length: " + request.getContentLength() + "\r\n").getBytes()); - } - buffer.put(LINE); - buffer.flip(); - final AsyncConnection remote = AsyncConnection.create("TCP", request.getHostSocketAddress(), 6, 6); - remote.write(buffer, null, new CompletionHandler() { - - @Override - public void completed(Integer result, Void attachment) { - if (buffer.hasRemaining()) { - remote.write(buffer, attachment, this); - return; - } - response.getContext().offerBuffer(buffer); - new ProxyCompletionHandler(remote, request, response).completed(0, null); - } - - @Override - public void failed(Throwable exc, Void attachment) { - response.getContext().offerBuffer(buffer); - response.finish(true); - try { - remote.close(); - } catch (IOException ex) { - } - } - }); - } - - private void connect(SocksRequest request, SocksResponse response) throws IOException { - final InetSocketAddress remoteAddress = request.parseSocketAddress(); - final AsyncConnection remote = remoteAddress.getPort() == 443 - ? AsyncConnection.create(Utility.createDefaultSSLSocket(remoteAddress)) : AsyncConnection.create("TCP", remoteAddress, 6, 6); - final ByteBuffer buffer0 = response.getContext().pollBuffer(); - buffer0.put("HTTP/1.1 200 Connection established\r\nConnection: close\r\n\r\n".getBytes()); - buffer0.flip(); - response.sendBody(buffer0, null, new CompletionHandler() { - - @Override - public void completed(Integer result, Void attachment) { - new ProxyCompletionHandler(remote, request, response).completed(0, null); - } - - @Override - public void failed(Throwable exc, Void attachment) { - response.finish(true); - try { - remote.close(); - } catch (IOException ex) { - } - } - }); - - } - - private static class ProxyCompletionHandler implements CompletionHandler { - - private AsyncConnection remote; - - private SocksRequest request; - - private SocksResponse response; - - public ProxyCompletionHandler(AsyncConnection remote, SocksRequest request, SocksResponse response) { - this.remote = remote; - this.request = request; - this.response = response; - } - - @Override - public void completed(Integer result0, Void v0) { - final ByteBuffer rbuffer = request.getContext().pollBuffer(); - remote.read(rbuffer, null, new CompletionHandler() { - - @Override - public void completed(Integer result, Void attachment) { - rbuffer.flip(); - CompletionHandler parent = this; - response.sendBody(rbuffer.duplicate().asReadOnlyBuffer(), null, new CompletionHandler() { - - @Override - public void completed(Integer result, Void attachment) { - rbuffer.clear(); - remote.read(rbuffer, attachment, parent); - } - - @Override - public void failed(Throwable exc, Void attachment) { - parent.failed(exc, attachment); - } - }); - } - - @Override - public void failed(Throwable exc, Void attachment) { - response.getContext().offerBuffer(rbuffer); - response.finish(true); - try { - remote.close(); - } catch (IOException ex) { - } - } - }); - - final ByteBuffer qbuffer = request.getContext().pollBuffer(); - request.getChannel().read(qbuffer, null, new CompletionHandler() { - - @Override - public void completed(Integer result, Void attachment) { - qbuffer.flip(); - CompletionHandler parent = this; - remote.write(qbuffer, null, new CompletionHandler() { - - @Override - public void completed(Integer result, Void attachment) { - qbuffer.clear(); - request.getChannel().read(qbuffer, null, parent); - } - - @Override - public void failed(Throwable exc, Void attachment) { - parent.failed(exc, attachment); - } - }); - } - - @Override - public void failed(Throwable exc, Void attachment) { - response.getContext().offerBuffer(qbuffer); - response.finish(true); - try { - remote.close(); - } catch (IOException ex) { - } - } - }); - } - - @Override - public void failed(Throwable exc, Void v) { - response.finish(true); - try { - remote.close(); - } catch (IOException ex) { - } - } - } - -} diff --git a/src-plugin/com/wentch/redkale/net/socks/SocksRequest.java b/src-plugin/com/wentch/redkale/net/socks/SocksRequest.java deleted file mode 100644 index 62d5d9c6c..000000000 --- a/src-plugin/com/wentch/redkale/net/socks/SocksRequest.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.wentch.redkale.net.socks; - -import com.wentch.redkale.net.*; -import com.wentch.redkale.net.http.*; -import java.net.*; -import java.nio.*; - -/** - * - * @author zhangjx - */ -public class SocksRequest extends HttpRequest { - - private boolean http; - - private short requestid; - - protected SocksRequest(HttpContext context) { - super(context, null); - } - - @Override - protected int readHeader(ByteBuffer buffer) { - if (buffer.get(0) > 0x05 && buffer.remaining() > 3) { - this.http = true; - return super.readHeader(buffer); - } - this.http = false; - if (buffer.get() != 0x05) return -1; - if (buffer.get() != 0x01) return -1; - if (buffer.get() != 0x00) return -1; - return 0; - } - - protected InetSocketAddress parseSocketAddress() { - return HttpRequest.parseSocketAddress(getRequestURI()); - } - - @Override - protected InetSocketAddress getHostSocketAddress() { - return super.getHostSocketAddress(); - } - - @Override - protected AsyncConnection getChannel() { - return super.getChannel(); - } - - @Override - protected int readBody(ByteBuffer buffer) { - return buffer.remaining(); - } - - @Override - protected void prepare() { - super.prepare(); - } - - @Override - protected void recycle() { - this.requestid = 0; - this.http = false; - super.recycle(); - } - - public short getRequestid() { - return requestid; - } - - public void setRequestid(short requestid) { - this.requestid = requestid; - } - - public boolean isHttp() { - return http; - } - - public void setHttp(boolean http) { - this.http = http; - } - -} diff --git a/src-plugin/com/wentch/redkale/net/socks/SocksResponse.java b/src-plugin/com/wentch/redkale/net/socks/SocksResponse.java deleted file mode 100644 index fca6c3306..000000000 --- a/src-plugin/com/wentch/redkale/net/socks/SocksResponse.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.wentch.redkale.net.socks; - -import com.wentch.redkale.net.*; -import com.wentch.redkale.net.http.*; -import com.wentch.redkale.util.*; -import java.util.concurrent.atomic.*; - -/** - * - * @author zhangjx - */ -public class SocksResponse extends HttpResponse { - - protected SocksResponse(Context context, SocksRequest request) { - super(context, request, (String[][]) null, (String[][]) null, null); - } - - public static ObjectPool createPool(AtomicLong creatCounter, AtomicLong cycleCounter, int max, Creator creator) { - return new ObjectPool<>(creatCounter, cycleCounter, max, creator, (x) -> ((SocksResponse) x).prepare(), (x) -> ((SocksResponse) x).recycle()); - } - - @Override - public AsyncConnection removeChannel() { - return super.removeChannel(); - } - -} diff --git a/src-plugin/com/wentch/redkale/net/socks/SocksRunner.java b/src-plugin/com/wentch/redkale/net/socks/SocksRunner.java deleted file mode 100644 index 7ab1af3d9..000000000 --- a/src-plugin/com/wentch/redkale/net/socks/SocksRunner.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.wentch.redkale.net.socks; - -import com.wentch.redkale.net.*; -import java.net.*; -import java.nio.*; -import java.nio.channels.*; -import java.util.logging.*; - -/** - * - * @author zhangjx - */ -public class SocksRunner implements Runnable { - - private final AsyncConnection channel; - - private final Logger logger; - - private final boolean finest; - - private final Context context; - - private final byte[] bindAddressBytes; - - private ByteBuffer buffer; - - protected boolean closed = false; - - private InetSocketAddress remoteAddress; - - private AsyncConnection remoteChannel; - - public SocksRunner(Context context, AsyncConnection channel, final byte[] bindAddressBytes) { - this.context = context; - this.logger = context.getLogger(); - this.finest = this.context.getLogger().isLoggable(Level.FINEST); - this.channel = channel; - this.buffer = context.pollBuffer(); - this.bindAddressBytes = bindAddressBytes; - } - - @Override - public void run() { - try { - ask(); - } catch (Exception e) { - closeRunner(e); - } - } - - private void ask() { - buffer.putChar((char) 0x0500); - buffer.flip(); - this.channel.write(buffer, null, new CompletionHandler() { - - @Override - public void completed(Integer result, Void attachment) { - if (buffer.hasRemaining()) { - channel.write(buffer, null, this); - return; - } - try { - connect(); - } catch (Exception e) { - closeRunner(e); - } - } - - @Override - public void failed(Throwable exc, Void attachment) { - closeRunner(exc); - } - }); - } - - private void connect() { - buffer.clear(); - this.channel.read(buffer, null, new CompletionHandler() { - - @Override - public void completed(Integer result, Void attachment) { - buffer.flip(); - if (buffer.getChar() != 0x0501) { - if (finest) logger.finest("connect header not 0x0501"); - closeRunner(null); - return; - } - char addrtype = buffer.getChar(); //0x0001 - 4 ; 0x0003 - x ; 0x0004 - 16 - try { - byte[] bytes = new byte[(addrtype == 0x0003) ? (buffer.get() & 0xff) : (addrtype * 4)]; - buffer.get(bytes); - remoteAddress = new InetSocketAddress((addrtype == 0x0003) ? InetAddress.getByName(new String(bytes)) : InetAddress.getByAddress(bytes), buffer.getChar()); - } catch (UnknownHostException e) { - failed(e, attachment); - return; - } - try { - remoteChannel = AsyncConnection.create("TCP", remoteAddress, 6, 6); - buffer.clear(); - buffer.putChar((char) 0x0500); - buffer.put((byte) 0x00); //rsv - buffer.put(bindAddressBytes); - buffer.flip(); - channel.write(buffer, null, new CompletionHandler() { - - @Override - public void completed(Integer result, Void attachment) { - if (buffer.hasRemaining()) { - channel.write(buffer, null, this); - return; - } - stream(); - } - - @Override - public void failed(Throwable exc, Void attachment) { - closeRunner(exc); - } - }); - } catch (Exception e) { - buffer.clear(); - buffer.putChar((char) 0x0504); - if (finest) logger.log(Level.FINEST, remoteAddress + " remote connect error", e); - channel.write(buffer, null, new CompletionHandler() { - - @Override - public void completed(Integer result, Void attachment) { - if (buffer.hasRemaining()) { - channel.write(buffer, null, this); - return; - } - closeRunner(null); - } - - @Override - public void failed(Throwable exc, Void attachment) { - closeRunner(exc); - } - }); - } - } - - @Override - public void failed(Throwable exc, Void attachment) { - closeRunner(exc); - } - }); - } - - private void stream() { - new StreamCompletionHandler(channel, remoteChannel).completed(0, null); - new StreamCompletionHandler(remoteChannel, channel).completed(0, null); - } - - public void closeRunner(final Throwable e) { - if (closed) return; - synchronized (this) { - if (closed) return; - closed = true; - try { - channel.close(); - } catch (Throwable t) { - } - context.offerBuffer(buffer); - buffer = null; - if (e != null && finest) { - logger.log(Level.FINEST, "close socks channel by error", e); - } - } - } - - private class StreamCompletionHandler implements CompletionHandler { - - private final AsyncConnection conn1; - - private final AsyncConnection conn2; - - private final ByteBuffer rbuffer; - - public StreamCompletionHandler(AsyncConnection conn1, AsyncConnection conn2) { - this.conn1 = conn1; - this.conn2 = conn2; - this.rbuffer = context.pollBuffer(); - this.rbuffer.flip(); - } - - @Override - public void completed(Integer result0, Void v0) { - final CompletionHandler self = this; - if (rbuffer.hasRemaining()) { - conn2.write(rbuffer, null, self); - return; - } - rbuffer.clear(); - conn1.read(rbuffer, null, new CompletionHandler() { - - @Override - public void completed(Integer result, Void attachment) { - rbuffer.flip(); - conn2.write(rbuffer, attachment, self); - } - - @Override - public void failed(Throwable exc, Void attachment) { - self.failed(exc, attachment); - } - }); - } - - @Override - public void failed(Throwable exc, Void v) { - context.offerBuffer(rbuffer); - conn1.dispose(); - conn2.dispose(); - if (finest) logger.log(Level.FINEST, "StreamCompletionHandler closed", exc); - } - } -} diff --git a/src-plugin/com/wentch/redkale/net/socks/SocksServer.java b/src-plugin/com/wentch/redkale/net/socks/SocksServer.java deleted file mode 100644 index d7d628f26..000000000 --- a/src-plugin/com/wentch/redkale/net/socks/SocksServer.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.wentch.redkale.net.socks; - -import com.wentch.redkale.net.*; -import com.wentch.redkale.net.http.*; -import com.wentch.redkale.util.*; -import com.wentch.redkale.watch.*; -import java.nio.*; -import java.util.concurrent.atomic.*; - -/** - * - * @author zhangjx - */ -public final class SocksServer extends Server { - - public SocksServer() { - this(System.currentTimeMillis(), null); - } - - public SocksServer(long serverStartTime, final WatchFactory watch) { - super(serverStartTime, "TCP", new SocksPrepareServlet(), watch); - } - - @Override - public void init(AnyValue config) throws Exception { - super.init(config); - } - - public void addSocksServlet(SocksServlet servlet, AnyValue conf) { - ((SocksPrepareServlet) this.prepare).setSocksServlet(servlet, conf); - } - - @Override - @SuppressWarnings("unchecked") - protected Context createContext() { - final int port = this.address.getPort(); - AtomicLong createBufferCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("SOCKS_" + port + ".Buffer.creatCounter"); - AtomicLong cycleBufferCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("SOCKS_" + port + ".Buffer.cycleCounter"); - int rcapacity = Math.max(this.capacity, 8 * 1024); - ObjectPool bufferPool = new ObjectPool<>(createBufferCounter, cycleBufferCounter, this.bufferPoolSize, - (Object... params) -> ByteBuffer.allocateDirect(rcapacity), null, (e) -> { - if (e == null || e.isReadOnly() || e.capacity() != rcapacity) return false; - e.clear(); - return true; - }); - AtomicLong createResponseCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("SOCKS_" + port + ".Response.creatCounter"); - AtomicLong cycleResponseCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("SOCKS_" + port + ".Response.cycleCounter"); - ObjectPool responsePool = SocksResponse.createPool(createResponseCounter, cycleResponseCounter, this.responsePoolSize, null); - HttpContext localcontext = new HttpContext(this.serverStartTime, this.logger, executor, rcapacity, bufferPool, responsePool, - this.maxbody, this.charset, this.address, this.prepare, this.watch, this.readTimeoutSecond, this.writeTimeoutSecond, ""); - responsePool.setCreator((Object... params) -> new SocksResponse(localcontext, new SocksRequest(localcontext))); - return localcontext; - } -} diff --git a/src-plugin/com/wentch/redkale/net/socks/SocksServlet.java b/src-plugin/com/wentch/redkale/net/socks/SocksServlet.java deleted file mode 100644 index b8b915071..000000000 --- a/src-plugin/com/wentch/redkale/net/socks/SocksServlet.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.wentch.redkale.net.socks; - -import com.wentch.redkale.net.*; -import com.wentch.redkale.util.*; - -/** - * - * @author zhangjx - */ -public abstract class SocksServlet implements Servlet { - - AnyValue conf; //当前Servlet的配置 - - @Override - public final boolean equals(Object obj) { - return obj != null && obj.getClass() == this.getClass(); - } - - @Override - public final int hashCode() { - return this.getClass().hashCode(); - } -} diff --git a/src-plugin/com/wentch/redkale/service/apns/ApnsMessage.java b/src-plugin/com/wentch/redkale/service/apns/ApnsMessage.java deleted file mode 100644 index 808860576..000000000 --- a/src-plugin/com/wentch/redkale/service/apns/ApnsMessage.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.wentch.redkale.service.apns; - -import com.wentch.redkale.convert.json.*; - -/** - * - * @author zhangjx - */ -public class ApnsMessage { - - public static final int PRIORITY_IMMEDIATELY = 10; - - public static final int PRIORITY_A_TIME = 5; - - private ApnsPayload payload; - - private int expiredate; - - private int priority = PRIORITY_IMMEDIATELY; - - private int identifier; - - private String token; - - public ApnsMessage() { - } - - public ApnsMessage(String token, ApnsPayload payload) { - this(token, payload, 0); - } - - public ApnsMessage(String token, ApnsPayload payload, int expiredate) { - this(token, payload, expiredate, PRIORITY_IMMEDIATELY); - } - - public ApnsMessage(String token, ApnsPayload payload, int expiredate, int priority) { - this.token = token; - this.payload = payload; - this.expiredate = expiredate; - this.priority = priority; - } - - public String getToken() { - return token; - } - - public void setToken(String token) { - this.token = token; - } - - public int getExpiredate() { - return expiredate; - } - - public void setExpiredate(int expiredate) { - this.expiredate = expiredate; - } - - public int getPriority() { - return priority; - } - - public void setPriority(int priority) { - this.priority = priority; - } - - public ApnsPayload getPayload() { - return payload; - } - - public void setPayload(ApnsPayload payload) { - this.payload = payload; - } - - public int getIdentifier() { - return identifier; - } - - public void setIdentifier(int identifier) { - this.identifier = identifier; - } - - @Override - public String toString() { - return JsonFactory.root().getConvert().convertTo(this); - } - -} diff --git a/src-plugin/com/wentch/redkale/service/apns/ApnsPayload.java b/src-plugin/com/wentch/redkale/service/apns/ApnsPayload.java deleted file mode 100644 index 3d294568d..000000000 --- a/src-plugin/com/wentch/redkale/service/apns/ApnsPayload.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.wentch.redkale.service.apns; - -import com.wentch.redkale.convert.json.*; -import java.util.*; -import java.util.regex.*; - -/** - * - * @author zhangjx - */ -public class ApnsPayload { - - private static final Pattern regex = Pattern.compile("\""); - - //----------------------- alert --------------------------------- - private String alertTitle; - - private String alertBody; - - private String alertTitleLocKey; - - private String[] alertTitleLocArgs; - - private String alertActionLocKey; - - private String alertLocKey; - - private String[] alertLocArgs; - - private String alertLaunchImage; - - //-------------------------------------------------------- - private int contentAvailable; - - private String alert; - - private int badge; - - private String sound; - - private final Map attributes = new HashMap<>(); - - public ApnsPayload() { - } - - public ApnsPayload(String alert, int badge) { - this.alert = alert; - this.badge = badge; - } - - public ApnsPayload(String title, String body, int badge) { - this.alertTitle = title; - this.alertBody = body; - this.badge = badge; - } - - public void putAttribute(String name, Object value) { - attributes.put(name, value); - } - - public void removeAttribute(String name) { - attributes.remove(name); - } - - public T getAttribute(String name) { - return (T) attributes.get(name); - } - - public Map getAttributes() { - return attributes; - } - - public void setAttributes(Map map) { - if (map != null) attributes.putAll(map); - } - - @Override - public String toString() { - StringBuilder alertsb = new StringBuilder(); - if (alert != null) { - alertsb.append('"').append(regex.matcher(alert).replaceAll("\\\"")).append('"'); - } else { - alertsb.append('{'); - if (alertTitle != null) { - if (alertsb.length() > 1) alertsb.append(','); - alertsb.append("\"title\":\"").append(regex.matcher(alertTitle).replaceAll("\\\"")).append('"'); - } - if (alertBody != null) { - if (alertsb.length() > 1) alertsb.append(','); - alertsb.append("\"body\":\"").append(regex.matcher(alertBody).replaceAll("\\\"")).append('"'); - } - if (alertTitleLocKey != null) { - if (alertsb.length() > 1) alertsb.append(','); - alertsb.append("\"title-loc-key\":\"").append(regex.matcher(alertTitleLocKey).replaceAll("\\\"")).append('"'); - } - if (alertTitleLocArgs != null && alertTitleLocArgs.length > 0) { - if (alertsb.length() > 1) alertsb.append(','); - alertsb.append("\"title-loc-args\":["); - boolean first = true; - for (String str : alertTitleLocArgs) { - if (!first) alertsb.append(','); - alertsb.append('"').append(regex.matcher(str).replaceAll("\\\"")).append('"'); - first = false; - } - alertsb.append(']'); - } - if (alertActionLocKey != null) { - if (alertsb.length() > 1) alertsb.append(','); - alertsb.append("\"action-loc-key\":\"").append(regex.matcher(alertActionLocKey).replaceAll("\\\"")).append('"'); - } - if (alertLocKey != null) { - if (alertsb.length() > 1) alertsb.append(','); - alertsb.append("\"loc-key\":\"").append(regex.matcher(alertLocKey).replaceAll("\\\"")).append('"'); - } - if (alertLocArgs != null && alertLocArgs.length > 0) { - if (alertsb.length() > 1) alertsb.append(','); - alertsb.append("\"loc-args\":["); - boolean first = true; - for (String str : alertLocArgs) { - if (!first) alertsb.append(','); - alertsb.append('"').append(regex.matcher(str).replaceAll("\\\"")).append('"'); - first = false; - } - alertsb.append(']'); - } - if (alertLaunchImage != null) { - if (alertsb.length() > 1) alertsb.append(','); - alertsb.append("\"launch-image\":\"").append(regex.matcher(alertLaunchImage).replaceAll("\\\"")).append('"'); - } - alertsb.append('}'); - } - final StringBuilder sb = new StringBuilder(); - sb.append("{\"aps\":{\"alert\":").append(alertsb); - if (badge > 0) sb.append(",\"badge\":").append(badge); - if (contentAvailable > 0) sb.append(",\"content-available\":").append(contentAvailable); - if (sound != null) sb.append(",\"sound\":\"").append(sound).append('"'); - sb.append("}"); - if (attributes.isEmpty()) { - sb.append('}'); - } else { - sb.append(',').append(JsonFactory.root().getConvert().convertTo(attributes).substring(1)); - } - return sb.toString(); - } - - public String getAlertTitle() { - return alertTitle; - } - - public void setAlertTitle(String alertTitle) { - this.alertTitle = alertTitle; - } - - public String getAlertBody() { - return alertBody; - } - - public void setAlertBody(String alertBody) { - this.alertBody = alertBody; - } - - public String getAlertTitleLocKey() { - return alertTitleLocKey; - } - - public void setAlertTitleLocKey(String alertTitleLocKey) { - this.alertTitleLocKey = alertTitleLocKey; - } - - public String[] getAlertTitleLocArgs() { - return alertTitleLocArgs; - } - - public void setAlertTitleLocArgs(String[] alertTitleLocArgs) { - this.alertTitleLocArgs = alertTitleLocArgs; - } - - public String getAlertActionLocKey() { - return alertActionLocKey; - } - - public void setAlertActionLocKey(String alertActionLocKey) { - this.alertActionLocKey = alertActionLocKey; - } - - public String getAlertLocKey() { - return alertLocKey; - } - - public void setAlertLocKey(String alertLocKey) { - this.alertLocKey = alertLocKey; - } - - public String[] getAlertLocArgs() { - return alertLocArgs; - } - - public void setAlertLocArgs(String[] alertLocArgs) { - this.alertLocArgs = alertLocArgs; - } - - public String getAlertLaunchImage() { - return alertLaunchImage; - } - - public void setAlertLaunchImage(String alertLaunchImage) { - this.alertLaunchImage = alertLaunchImage; - } - - public int getContentAvailable() { - return contentAvailable; - } - - public void setContentAvailable(int contentAvailable) { - this.contentAvailable = contentAvailable; - } - - public String getAlert() { - return alert; - } - - public void setAlert(String alert) { - this.alert = alert; - } - - public int getBadge() { - return badge; - } - - public void setBadge(int badge) { - this.badge = badge; - } - - public String getSound() { - return sound; - } - - public void setSound(String sound) { - this.sound = sound; - } - -} diff --git a/src-plugin/com/wentch/redkale/service/apns/ApnsService.java b/src-plugin/com/wentch/redkale/service/apns/ApnsService.java deleted file mode 100644 index 4c1e5c28b..000000000 --- a/src-plugin/com/wentch/redkale/service/apns/ApnsService.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.wentch.redkale.service.apns; - -import com.wentch.redkale.convert.json.*; -import com.wentch.redkale.service.*; -import com.wentch.redkale.util.*; -import java.io.*; -import java.net.*; -import java.nio.*; -import java.nio.charset.*; -import java.security.*; -import java.util.concurrent.*; -import java.util.logging.*; -import javax.annotation.*; -import javax.net.ssl.*; - -/** - * - * @author zhangjx - */ -@AutoLoad(false) -@LocalService -public class ApnsService implements Service { - - private static final Charset UTF8 = Charset.forName("UTF-8"); - - protected final Logger logger = Logger.getLogger(this.getClass().getSimpleName()); - - @Resource - protected JsonConvert convert; - - @Resource(name = "property.apns.certpwd") - protected String apnscertpwd = "1"; //证书的密码 - - @Resource(name = "property.apns.certpath") //用来加载证书用 - protected String apnscertpath = "apnspushdev_cert.p12"; - - @Resource(name = "property.apns.pushaddr") // - protected String apnspushaddr = "gateway.sandbox.push.apple.com"; - - @Resource(name = "property.apns.pushport") // - protected int apnspushport = 2195; - - @Resource(name = "property.apns.buffersize") // - protected int apnsbuffersize = 4096; - - private boolean inited = false; - - private final CountDownLatch cdl = new CountDownLatch(1); - - private SSLSocketFactory sslFactory; - - @Override - public void init(AnyValue conf) { - new Thread() { - { - setDaemon(true); - setPriority(Thread.MAX_PRIORITY); - } - - @Override - public void run() { - try { - final String path = "/" + this.getClass().getPackage().getName().replace('.', '/') + "/" + apnscertpath; - KeyStore ks = KeyStore.getInstance("PKCS12"); - InputStream in = ApnsService.class.getResourceAsStream(path); - KeyManagerFactory kf = null; - if (in != null) { - ks.load(in, apnscertpwd.toCharArray()); - in.close(); - kf = KeyManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - kf.init(ks, apnscertpwd.toCharArray()); - } - - TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - tmf.init((KeyStore) null); - SSLContext context = SSLContext.getInstance("TLS"); - context.init(kf == null ? new KeyManager[0] : kf.getKeyManagers(), tmf.getTrustManagers(), null); - ApnsService.this.sslFactory = context.getSocketFactory(); - } catch (Exception e) { - logger.log(Level.SEVERE, this.getClass().getSimpleName() + " init SSLContext error", e); - } finally { - inited = true; - cdl.countDown(); - } - } - }.start(); - } - - @Override - public void destroy(AnyValue conf) { - } - - private Socket getPushSocket() throws IOException { - if (!this.inited) { - try { - cdl.await(); - } catch (InterruptedException e) { - } - } - Socket pushSocket = sslFactory.createSocket(apnspushaddr, apnspushport); - pushSocket.setTcpNoDelay(true); - return pushSocket; - } - - public void pushApnsMessage(ApnsMessage message) throws IOException { - final byte[] tokens = Utility.hexToBin(message.getToken().replaceAll("\\s+", "")); - ByteBuffer buffer = ByteBuffer.allocate(apnsbuffersize); - buffer.put((byte) 2); //固定命令号 - buffer.putInt(0); //下面数据的长度 - - buffer.put((byte) 1); //token - buffer.putShort((short) tokens.length); - buffer.put(tokens); - - buffer.put((byte) 2); //payload - final byte[] payload = message.getPayload().toString().getBytes(UTF8); - buffer.putShort((short) payload.length); - buffer.put(payload); - - if (message.getIdentifier() > 0) { - buffer.put((byte) 3); //Notification identifier - buffer.putShort((short) 4); - buffer.putInt(message.getIdentifier()); - } - if (message.getExpiredate() > 0) { - buffer.put((byte) 4); //Expiration date - buffer.putShort((short) 4); - buffer.putInt(message.getExpiredate()); - } - buffer.put((byte) 5); //Priority - buffer.putShort((short) 1); - buffer.put((byte) message.getPriority()); - - final int pos = buffer.position(); - buffer.position(1); - buffer.putInt(pos - 5); - buffer.position(pos); - buffer.flip(); - - Socket socket = getPushSocket(); - socket.getOutputStream().write(buffer.array(), 0, buffer.remaining()); - socket.close(); - } - - public static void main(String[] args) throws Exception { - ApnsService service = new ApnsService(); - service.convert = JsonFactory.root().getConvert(); - service.init(null); - - final String token = "01727b19 b9f8abf4 0891e31d 3446479d a43902e1 819edc44 a073d951 b8b7db90"; - ApnsPayload payload = new ApnsPayload("您有新的消息", "这是消息内容", 1); - System.out.println(payload); - service.pushApnsMessage(new ApnsMessage(token, payload)); - } - -} diff --git a/src-plugin/com/wentch/redkale/service/weixin/WeiXinMPService.java b/src-plugin/com/wentch/redkale/service/weixin/WeiXinMPService.java deleted file mode 100644 index d0e703e50..000000000 --- a/src-plugin/com/wentch/redkale/service/weixin/WeiXinMPService.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.wentch.redkale.service.weixin; - -import com.wentch.redkale.convert.json.*; -import static com.wentch.redkale.convert.json.JsonConvert.TYPE_MAP_STRING_STRING; -import com.wentch.redkale.service.*; -import com.wentch.redkale.util.*; -import static com.wentch.redkale.util.Utility.getHttpContent; -import java.io.*; -import java.security.*; -import java.util.*; -import java.util.logging.*; -import javax.annotation.*; - -/** - * 微信服务号Service - * - * @author zhangjx - */ -@AutoLoad(false) -@LocalService -public class WeiXinMPService implements Service { - - protected final Logger logger = Logger.getLogger(this.getClass().getSimpleName()); - - private final boolean finest = logger.isLoggable(Level.FINEST); - - private final boolean finer = logger.isLoggable(Level.FINER); - - protected final Map mpsecrets = new HashMap<>(); - - @Resource - protected JsonConvert convert; - - // http://m.xxx.com/pipes/wx/verifymp - @Resource(name = "property.wxmp.token") - protected String mptoken = ""; - - @Resource(name = "property.wxmp.corpid") - protected String mpcorpid = "wxYYYYYYYYYYYYYY"; - - @Resource(name = "property.wxmp.aeskey") - protected String mpaeskey = ""; - - public WeiXinMPService() { - // mpsecrets.put("wxYYYYYYYYYYYYYYYYYY", "xxxxxxxxxxxxxxxxxxxxxxxxxxx"); - } - - //-----------------------------------微信服务号接口---------------------------------------------------------- - public RetResult getMPWxunionidByCode(String appid, String code) { - try { - Map wxmap = getMPUserTokenByCode(appid, code); - final String unionid = wxmap.get("unionid"); - if (unionid != null && !unionid.isEmpty()) return new RetResult<>(unionid); - return new RetResult<>(1011002); - } catch (IOException e) { - return new RetResult<>(1011001); - } - } - - public Map getMPUserTokenByCode(String appid, String code) throws IOException { - String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appid + "&secret=" + mpsecrets.get(appid) + "&code=" + code + "&grant_type=authorization_code"; - String json = getHttpContent(url); - if (finest) logger.finest(url + "--->" + json); - Map jsonmap = convert.convertFrom(TYPE_MAP_STRING_STRING, json); - return getMPUserTokenByOpenid(jsonmap.get("access_token"), jsonmap.get("openid")); - } - - public Map getMPUserTokenByOpenid(String access_token, String openid) throws IOException { - String url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token + "&openid=" + openid; - String json = getHttpContent(url); - if (finest) logger.finest(url + "--->" + json); - Map jsonmap = convert.convertFrom(TYPE_MAP_STRING_STRING, json.replaceFirst("\\[.*\\]", "null")); - return jsonmap; - } - - public String verifyMPURL(String msgSignature, String timeStamp, String nonce, String echoStr) { - String signature = sha1(mptoken, timeStamp, nonce); - if (!signature.equals(msgSignature)) throw new RuntimeException("signature verification error"); - return echoStr; - } - - /** - * 用SHA1算法生成安全签名 - *

- * @param strings - * @return 安全签名 - */ - protected static String sha1(String... strings) { - try { - Arrays.sort(strings); - MessageDigest md = MessageDigest.getInstance("SHA-1"); - for (String s : strings) md.update(s.getBytes()); - return Utility.binToHexString(md.digest()); - } catch (Exception e) { - throw new RuntimeException("SHA encryption to generate signature failure", e); - } - } -} diff --git a/src-plugin/com/wentch/redkale/service/weixin/WeiXinPayResult.java b/src-plugin/com/wentch/redkale/service/weixin/WeiXinPayResult.java deleted file mode 100644 index 6a41ea52c..000000000 --- a/src-plugin/com/wentch/redkale/service/weixin/WeiXinPayResult.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.wentch.redkale.service.weixin; - -import com.wentch.redkale.service.*; - -/** - * - * @author zhangjx - */ -public class WeiXinPayResult extends RetResult { - - //待支付 - public static final short PAYSTATUS_UNPAY = 10; - - //已支付 - public static final short PAYSTATUS_PAYOK = 30; - - private long orderid; - - private long payid; - - private long payedmoney; - - private short paystatus; - - public WeiXinPayResult() { - } - - public WeiXinPayResult(int retcode) { - super(retcode); - } - - public WeiXinPayResult(long orderid, long payid, short paystatus, long payedmoney, String resultcontent) { - this.orderid = orderid; - this.payid = payid; - this.paystatus = paystatus; - this.payedmoney = payedmoney; - this.setResult(resultcontent); - } - - public long getOrderid() { - return orderid; - } - - public void setOrderid(long orderid) { - this.orderid = orderid; - } - - public long getPayid() { - return payid; - } - - public void setPayid(long payid) { - this.payid = payid; - } - - public long getPayedmoney() { - return payedmoney; - } - - public void setPayedmoney(long payedmoney) { - this.payedmoney = payedmoney; - } - - public short getPaystatus() { - return paystatus; - } - - public void setPaystatus(short paystatus) { - this.paystatus = paystatus; - } - -} diff --git a/src-plugin/com/wentch/redkale/service/weixin/WeiXinPayService.java b/src-plugin/com/wentch/redkale/service/weixin/WeiXinPayService.java deleted file mode 100644 index eaf2ed4cf..000000000 --- a/src-plugin/com/wentch/redkale/service/weixin/WeiXinPayService.java +++ /dev/null @@ -1,256 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.wentch.redkale.service.weixin; - -import com.wentch.redkale.convert.json.*; -import com.wentch.redkale.service.*; -import static com.wentch.redkale.service.weixin.WeiXinPayResult.*; -import com.wentch.redkale.util.*; -import java.security.*; -import java.text.*; -import java.util.*; -import java.util.logging.*; -import java.util.regex.*; -import javax.annotation.*; - -/** - * - * @author zhangjx - */ -@AutoLoad(false) -@LocalService -public class WeiXinPayService implements Service { - - private static final DateFormat FORMAT = new SimpleDateFormat("yyyyMMddHHmmss"); - - private static final Pattern PAYXML = Pattern.compile("<([^/>]+)>(.+)"); // "<([^/>]+)>" - - public static final int PAY_WX_ERROR = 4012101;//微信支付失败 - - public static final int PAY_FALSIFY_ORDER = 4012017;//交易签名被篡改 - - public static final int PAY_STATUS_ERROR = 4012018;//订单或者支付状态不正确 - - protected final Logger logger = Logger.getLogger(this.getClass().getSimpleName()); - - protected final boolean fine = logger.isLoggable(Level.FINE); - - protected final boolean finer = logger.isLoggable(Level.FINER); - - protected final boolean finest = logger.isLoggable(Level.FINEST); - - @Resource(name = "property.wxpay.appid") //公众账号ID - protected String wxpayappid = "wxYYYYYYYYYYYY"; - - @Resource(name = "property.wxpay.mchid") //商户ID - protected String wxpaymchid = "xxxxxxxxxxx"; - - @Resource(name = "property.wxpay.sdbmchid") //子商户ID,受理模式必填 - protected String wxpaysdbmchid = ""; - - @Resource(name = "property.wxpay.key") //签名算法需要用到的秘钥 - protected String wxpaykey = "##########################"; - - @Resource(name = "property.wxpay.certpwd") - protected String wxpaycertpwd = "xxxxxxxxxx"; //HTTP证书的密码,默认等于MCHID - - @Resource(name = "property.wxpay.certpath") //HTTP证书在服务器中的路径,用来加载证书用 - protected String wxpaycertpath = "apiclient_cert.p12"; - - @Resource - protected JsonConvert convert; - - /** - * - * + " - * + " - * + " - * + " - * + " - * + " - * + " - * + " - * + " - *

- * @param orderid - * @param payid - * @param orderpayid - * @param paymoney - * @param clientAddr - * @param notifyurl - * @param map - * @return - */ - public RetResult> paying(long orderid, long payid, long orderpayid, long paymoney, String clientAddr, String notifyurl, Map map) { - RetResult result = null; - try { - if (!(map instanceof SortedMap)) map = new TreeMap<>(map); - map.put("appid", wxpayappid); - map.put("mch_id", wxpaymchid); - map.put("nonce_str", Long.toHexString(System.currentTimeMillis()) + Long.toHexString(System.nanoTime())); - map.putIfAbsent("body", "服务"); - map.put("attach", "" + payid); - map.put("out_trade_no", "" + orderpayid); - map.put("total_fee", "" + paymoney); - map.put("spbill_create_ip", clientAddr); - synchronized (FORMAT) { - map.put("time_expire", FORMAT.format(new Date(System.currentTimeMillis() + 10 * 60 * 60 * 1000))); - } - map.put("notify_url", notifyurl); - { - final StringBuilder sb = new StringBuilder(); - map.forEach((x, y) -> sb.append(x).append('=').append(y).append('&')); - sb.append("key=").append(wxpaykey); - map.put("sign", Utility.binToHexString(MessageDigest.getInstance("MD5").digest(sb.toString().getBytes())).toUpperCase()); - } - if (finest) logger.finest("weixinpaying2: " + orderid + " -> unifiedorder.map =" + map); - Map wxresult = formatXMLToMap(Utility.postHttpContent("https://api.mch.weixin.qq.com/pay/unifiedorder", formatMapToXML(map))); - if (finest) logger.finest("weixinpaying3: " + orderid + " -> unifiedorder.callback =" + wxresult); - if (!"SUCCESS".equals(wxresult.get("return_code"))) return new RetResult<>(PAY_WX_ERROR); - if (!checkSign(wxresult)) return new RetResult(PAY_FALSIFY_ORDER); - /** - * "appId" : "wx2421b1c4370ec43b", //公众号名称,由商户传入 "timeStamp":" 1395712654", //时间戳,自1970年以来的秒数 "nonceStr" : "e61463f8efa94090b1f366cccfbbb444", //随机串 "package" : - * "prepay_id=u802345jgfjsdfgsdg888", "signType" : "MD5", //微信签名方式: "paySign" : "70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名 - */ - Map rs = new TreeMap<>(); - rs.put("appId", this.wxpayappid); - rs.put("timeStamp", Long.toString(System.currentTimeMillis() / 1000)); - rs.put("nonceStr", Long.toHexString(System.currentTimeMillis()) + Long.toHexString(System.nanoTime())); - rs.put("package", "prepay_id=" + wxresult.get("prepay_id")); - rs.put("signType", "MD5"); - { - final StringBuilder sb2 = new StringBuilder(); - rs.forEach((x, y) -> sb2.append(x).append('=').append(y).append('&')); - sb2.append("key=").append(wxpaykey); - rs.put("paySign", Utility.binToHexString(MessageDigest.getInstance("MD5").digest(sb2.toString().getBytes())).toUpperCase()); - } - if (finest) logger.finest("weixinpaying4: " + orderid + " -> unifiedorder.result =" + rs); - RetResult rr = new RetResult(rs); - rr.setRetinfo("" + orderpayid); - return rr; - } catch (Exception e) { - logger.log(Level.WARNING, "paying error.", e); - } - return result; - } - - public RetResult closepay(long orderpayid) { - RetResult result = null; - try { - Map map = new TreeMap<>(); - map.put("appid", wxpayappid); - map.put("mch_id", wxpaymchid); - map.put("nonce_str", Long.toHexString(System.currentTimeMillis()) + Long.toHexString(System.nanoTime())); - map.put("out_trade_no", "" + orderpayid); - { - final StringBuilder sb = new StringBuilder(); - map.forEach((x, y) -> sb.append(x).append('=').append(y).append('&')); - sb.append("key=").append(wxpaykey); - map.put("sign", Utility.binToHexString(MessageDigest.getInstance("MD5").digest(sb.toString().getBytes())).toUpperCase()); - } - if (finest) logger.finest("weixinclosepay2: " + orderpayid + " -> closeorder.map =" + map); - Map wxresult = formatXMLToMap(Utility.postHttpContent("https://api.mch.weixin.qq.com/pay/closeorder", formatMapToXML(map))); - if (finest) logger.finest("weixinclosepay3: " + orderpayid + " -> closeorder.callback =" + wxresult); - if (!"SUCCESS".equals(wxresult.get("return_code"))) return new RetResult<>(PAY_WX_ERROR); - if (!checkSign(wxresult)) return new RetResult(PAY_FALSIFY_ORDER); - return new RetResult(wxresult); - } catch (Exception e) { - logger.log(Level.WARNING, "closepay error: " + orderpayid, e); - } - return result; - } - - public WeiXinPayResult checkPay(long orderid, long orderpayid) { - WeiXinPayResult result = new WeiXinPayResult(PAY_STATUS_ERROR); - try { - Map map = new TreeMap<>(); - map.put("appid", wxpayappid); - map.put("mch_id", wxpaymchid); - map.put("out_trade_no", "" + orderpayid); - map.put("nonce_str", Long.toHexString(System.currentTimeMillis()) + Long.toHexString(System.nanoTime())); - { - final StringBuilder sb = new StringBuilder(); - map.forEach((x, y) -> sb.append(x).append('=').append(y).append('&')); - sb.append("key=").append(wxpaykey); - map.put("sign", Utility.binToHexString(MessageDigest.getInstance("MD5").digest(sb.toString().getBytes())).toUpperCase()); - } - Map wxresult = formatXMLToMap(Utility.postHttpContent("https://api.mch.weixin.qq.com/pay/orderquery", formatMapToXML(map))); - return callbackPay(wxresult); - } catch (Exception e) { - logger.log(Level.FINER, "check weixinpay[" + orderid + "] except", e); - return result; - } - } - - /** - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * 10 - * - * - * - *

- * @param map - * @return - */ - public WeiXinPayResult callbackPay(Map map) { - if (!"SUCCESS".equals(map.get("return_code"))) return new WeiXinPayResult(PAY_WX_ERROR); - if (!(map instanceof SortedMap)) map = new TreeMap<>(map); - if (!checkSign(map)) return new WeiXinPayResult(PAY_FALSIFY_ORDER); - String state = map.get("trade_state"); - if (state == null && "SUCCESS".equals(map.get("result_code")) && Long.parseLong(map.get("total_fee")) > 0) { - state = "SUCCESS"; - } - short paystatus = "SUCCESS".equals(state) ? PAYSTATUS_PAYOK : PAYSTATUS_UNPAY; - return new WeiXinPayResult(Long.parseLong(map.get("out_trade_no")), Long.parseLong(map.get("attach")), paystatus, Long.parseLong(map.get("total_fee")), convert.convertTo(map)); - } - - protected static String formatMapToXML(final Map map) { - final StringBuilder sb = new StringBuilder(); - sb.append(""); - map.forEach((x, y) -> sb.append('<').append(x).append('>').append(y.replace("<", "<").replace(">", ">").replace("&", "&")).append("')); - sb.append(""); - return sb.toString(); - } - - protected boolean checkSign(Map map) { - if (!(map instanceof SortedMap)) map = new TreeMap<>(map); - String sign = map.remove("sign"); - final StringBuilder sb = new StringBuilder(); - map.forEach((x, y) -> sb.append(x).append('=').append(y).append('&')); - sb.append("key=").append(wxpaykey); - try { - return sign.equals(Utility.binToHexString(MessageDigest.getInstance("MD5").digest(sb.toString().getBytes())).toUpperCase()); - } catch (Exception e) { - return false; - } - } - - public static Map formatXMLToMap(final String xml) { - Map map = new TreeMap<>(); - Matcher m = PAYXML.matcher(xml.substring(xml.indexOf('>') + 1)); - while (m.find()) { - String val = m.group(2); - if (val.startsWith(" text; - - private String touser = "@all"; - - private String toparty; - - private String totag; - - private String safe; - - private Supplier contentSupplier; - - public WeiXinQYMessage() { - } - - public WeiXinQYMessage(String agentid, String text) { - this.agentid = agentid; - setTextMessage(text); - } - - public WeiXinQYMessage(String agentid, Supplier contentSupplier) { - this.agentid = agentid; - this.contentSupplier = contentSupplier; - } - - public final void setTextMessage(String content) { - if (text == null) text = new HashMap<>(); - text.put("content", content); - } - - public void supplyContent() { - if (contentSupplier != null) setTextMessage(contentSupplier.get()); - } - - public String getAgentid() { - return agentid; - } - - public void setAgentid(String agentid) { - this.agentid = agentid; - } - - public String getMsgtype() { - return msgtype; - } - - public void setMsgtype(String msgtype) { - this.msgtype = msgtype; - } - - public Map getText() { - return text; - } - - public void setText(Map text) { - this.text = text; - } - - public String getTouser() { - return touser; - } - - public void setTouser(String touser) { - this.touser = touser; - } - - public String getToparty() { - return toparty; - } - - public void setToparty(String toparty) { - this.toparty = toparty; - } - - public String getTotag() { - return totag; - } - - public void setTotag(String totag) { - this.totag = totag; - } - - public String getSafe() { - return safe; - } - - public void setSafe(String safe) { - this.safe = safe; - } - - @Override - public String toString() { - return JsonFactory.root().getConvert().convertTo(this); - } -} diff --git a/src-plugin/com/wentch/redkale/service/weixin/WeiXinQYService.java b/src-plugin/com/wentch/redkale/service/weixin/WeiXinQYService.java deleted file mode 100644 index 18036d7c4..000000000 --- a/src-plugin/com/wentch/redkale/service/weixin/WeiXinQYService.java +++ /dev/null @@ -1,317 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.wentch.redkale.service.weixin; - -import com.wentch.redkale.boot.*; -import com.wentch.redkale.convert.json.*; -import com.wentch.redkale.net.*; -import com.wentch.redkale.service.*; -import com.wentch.redkale.util.*; -import static com.wentch.redkale.util.Utility.*; -import java.io.*; -import java.lang.reflect.*; -import java.nio.charset.*; -import java.security.*; -import java.util.*; -import java.util.function.*; -import java.util.logging.*; -import javax.annotation.*; -import javax.crypto.*; -import javax.crypto.spec.*; - -/** - * - * @author zhangjx - */ -@AutoLoad(false) -@LocalService -public class WeiXinQYService implements Service { - - protected final Logger logger = Logger.getLogger(this.getClass().getSimpleName()); - - private final boolean finest = logger.isLoggable(Level.FINEST); - - private final boolean finer = logger.isLoggable(Level.FINER); - - private static class Token { - - public String token; - - public long expires = 7100000; - - public long accesstime; - } - - private static final String BASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - - private static final Charset CHARSET = Charset.forName("UTF-8"); - - private static final Random RANDOM = new Random(); - - protected static final Type MAPTYPE = new TypeToken>() { - }.getType(); - - @Resource - protected JsonConvert convert; - - //------------------------------------------------------------------------------------------------------ - // http://oa.xxxx.com/pipes/wx/verifyqy - @Resource(name = "property.wxqy.token") - protected String qytoken = ""; - - @Resource(name = "property.wxqy.corpid") - protected String qycorpid = "wxYYYYYYYYYYYYYYYY"; - - @Resource(name = "property.wxqy.aeskey") - protected String qyaeskey = ""; - - @Resource(name = "property.wxqy.secret") - private String qysecret = "#########################"; - - private SecretKeySpec qykeyspec; - - private IvParameterSpec qyivspec; - - private final Token qyAccessToken = new Token(); - - //------------------------------------------------------------------------------------------------------ - public WeiXinQYService() { - } - - public static void main(String[] args) throws Exception { - WeiXinQYService service = Application.singleton(WeiXinQYService.class); - - WeiXinQYMessage message = new WeiXinQYMessage(); - message.setTextMessage("【测试】duang!"); - message.setAgentid("2"); - service.sendQYMessage(message); - } - - //-----------------------------------微信企业号接口---------------------------------------------------------- - public Map getQYUserCode(String code, String agentid) throws IOException { - String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=" + getQYAccessToken() + "&code=" + code + "&agentid=" + agentid; - String json = getHttpContent(url); - if (finest) logger.finest(url + "--->" + json); - return convert.convertFrom(MAPTYPE, json); - } - - public void sendQYTextMessage(String agentid, String message) { - sendQYMessage(new WeiXinQYMessage(agentid, message)); - } - - public void sendQYTextMessage(String agentid, Supplier contentSupplier) { - sendQYMessage(new WeiXinQYMessage(agentid, contentSupplier)); - } - - public void sendQYMessage(WeiXinQYMessage message) { - submit(() -> { - String result = null; - try { - message.supplyContent(); - String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + getQYAccessToken(); - result = postHttpContent(url, convert.convertTo(message)); - if (finest) logger.finest("sendQYMessage ok: " + message + " -> " + result); - } catch (Exception e) { - logger.log(Level.WARNING, "sendQYMessage error: " + message + " -> " + result, e); - } - }); - } - - public String verifyQYURL(String msgSignature, String timeStamp, String nonce, String echoStr) { - String signature = sha1(qytoken, timeStamp, nonce, echoStr); - if (!signature.equals(msgSignature)) throw new RuntimeException("signature verification error"); - return decryptQY(echoStr); - } - - protected String getQYAccessToken() throws IOException { - if (qyAccessToken.accesstime < System.currentTimeMillis() - qyAccessToken.expires) qyAccessToken.token = null; - if (qyAccessToken.token == null) { - String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + qycorpid + "&corpsecret=" + qysecret; - String json = getHttpContent(url); - if (finest) logger.finest(url + "--->" + json); - Map jsonmap = convert.convertFrom(MAPTYPE, json); - qyAccessToken.accesstime = System.currentTimeMillis(); - qyAccessToken.token = jsonmap.get("access_token"); - String exp = jsonmap.get("expires_in"); - if (exp != null) qyAccessToken.expires = (Integer.parseInt(exp) - 100) * 1000; - } - return qyAccessToken.token; - } - - /** - * 将公众平台回复用户的消息加密打包. - *

    - *
  1. 对要发送的消息进行AES-CBC加密
  2. - *
  3. 生成安全签名
  4. - *
  5. 将消息密文和安全签名打包成xml格式
  6. - *
- *

- * @param replyMsg 公众平台待回复用户的消息,xml格式的字符串 - * @param timeStamp 时间戳,可以自己生成,也可以用URL参数的timestamp - * @param nonce 随机串,可以自己生成,也可以用URL参数的nonce - *

- * @return 加密后的可以直接回复用户的密文,包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串 - */ - protected String encryptQYMessage(String replyMsg, String timeStamp, String nonce) { - // 加密 - String encrypt = encryptQY(random16String(), replyMsg); - - // 生成安全签名 - if (timeStamp == null || timeStamp.isEmpty()) timeStamp = Long.toString(System.currentTimeMillis()); - String signature = sha1(qytoken, timeStamp, nonce, encrypt); - - // System.out.println("发送给平台的签名是: " + signature[1].toString()); - // 生成发送的xml - return "\n\n" - + "\n" - + "" + timeStamp + "\n" - + "\n"; - } - - protected String decryptQYMessage(String msgSignature, String timeStamp, String nonce, String postData) { - // 密钥,公众账号的app secret - // 提取密文 - String encrypt = postData.substring(postData.indexOf("")); - // 验证安全签名 - if (!sha1(qytoken, timeStamp, nonce, encrypt).equals(msgSignature)) throw new RuntimeException("signature verification error"); - return decryptQY(encrypt); - } - - /** - * 对明文进行加密. - *

- * @param randomStr - * @param text 需要加密的明文 - * @return 加密后base64编码的字符串 - */ - protected String encryptQY(String randomStr, String text) { - ByteArray bytes = new ByteArray(); - byte[] randomStrBytes = randomStr.getBytes(CHARSET); - byte[] textBytes = text.getBytes(CHARSET); - byte[] corpidBytes = qycorpid.getBytes(CHARSET); - - // randomStr + networkBytesOrder + text + qycorpid - bytes.add(randomStrBytes); - bytes.addInt(textBytes.length); - bytes.add(textBytes); - bytes.add(corpidBytes); - - // ... + pad: 使用自定义的填充方式对明文进行补位填充 - byte[] padBytes = encodePKCS7(bytes.count()); - bytes.add(padBytes); - - // 获得最终的字节流, 未加密 - try { - // 加密 - byte[] encrypted = createQYCipher(Cipher.ENCRYPT_MODE).doFinal(bytes.directBytes(), 0, bytes.count()); - // 使用BASE64对加密后的字符串进行编码 - return Base64.getEncoder().encodeToString(encrypted); - } catch (Exception e) { - throw new RuntimeException("AES加密失败", e); - } - } - - protected String decryptQY(String text) { - byte[] original; - try { - // 使用BASE64对密文进行解码 - original = createQYCipher(Cipher.DECRYPT_MODE).doFinal(Base64.getDecoder().decode(text)); - } catch (Exception e) { - throw new RuntimeException("AES解密失败", e); - } - try { - // 去除补位字符 - byte[] bytes = decodePKCS7(original); - // 分离16位随机字符串,网络字节序和corpid - int xmlLength = (bytes[16] & 0xFF) << 24 | (bytes[17] & 0xFF) << 16 | (bytes[18] & 0xFF) << 8 | bytes[19] & 0xFF; - if (!qycorpid.equals(new String(bytes, 20 + xmlLength, bytes.length - 20 - xmlLength, CHARSET))) { - throw new RuntimeException("corpid校验失败"); - } - return new String(bytes, 20, xmlLength, CHARSET); - } catch (RuntimeException e) { - if (e.getMessage().contains("corpid")) throw e; - throw new RuntimeException("解密后得到的buffer非法", e); - } - } - - protected Cipher createQYCipher(int mode) throws Exception { - Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); //AES192、256位加密解密 需要将新版 local_policy.jar、US_export_policy.jar两个文件覆盖到 ${JDK_HOME}/jre/lib/security/下 - if (qykeyspec == null) { - byte[] aeskeyBytes = Base64.getDecoder().decode(qyaeskey + "="); - qykeyspec = new SecretKeySpec(aeskeyBytes, "AES"); - qyivspec = new IvParameterSpec(aeskeyBytes, 0, 16); - } - cipher.init(mode, qykeyspec, qyivspec); - return cipher; - } - - protected void submit(Runnable runner) { - Thread thread = Thread.currentThread(); - if (thread instanceof WorkThread) { - ((WorkThread) thread).submit(runner); - return; - } - runner.run(); - } - - //-----------------------------------通用接口---------------------------------------------------------- - // 随机生成16位字符串 - protected static String random16String() { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < 16; i++) { - sb.append(BASE.charAt(RANDOM.nextInt(BASE.length()))); - } - return sb.toString(); - } - - /** - * 用SHA1算法生成安全签名 - *

- * @param strings - * @return 安全签名 - */ - protected static String sha1(String... strings) { - try { - Arrays.sort(strings); - MessageDigest md = MessageDigest.getInstance("SHA-1"); - for (String s : strings) md.update(s.getBytes()); - return Utility.binToHexString(md.digest()); - } catch (Exception e) { - throw new RuntimeException("SHA encryption to generate signature failure", e); - } - } - - /** - * 获得对明文进行补位填充的字节. - *

- * @param count 需要进行填充补位操作的明文字节个数 - * @return 补齐用的字节数组 - */ - private static byte[] encodePKCS7(int count) { - // 计算需要填充的位数 - int amountToPad = 32 - (count % 32); - if (amountToPad == 0) amountToPad = 32; - // 获得补位所用的字符 - char padChr = (char) (byte) (amountToPad & 0xFF); - StringBuilder tmp = new StringBuilder(); - for (int index = 0; index < amountToPad; index++) { - tmp.append(padChr); - } - return tmp.toString().getBytes(CHARSET); - } - - /** - * 删除解密后明文的补位字符 - *

- * @param decrypted 解密后的明文 - * @return 删除补位字符后的明文 - */ - private static byte[] decodePKCS7(byte[] decrypted) { - int pad = (int) decrypted[decrypted.length - 1]; - if (pad < 1 || pad > 32) pad = 0; - return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad); - } -}