/*******************************************************************************
* Copyright (c) 2013 Hani Naguib.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* Hani Naguib - initial API and implementation
******************************************************************************/
package com.gvmax.relay.servlets;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.appengine.api.xmpp.Message;
import com.google.appengine.api.xmpp.MessageBuilder;
import com.google.appengine.api.xmpp.XMPPService;
import com.google.appengine.api.xmpp.XMPPServiceFactory;
import com.gvmax.common.util.Enc;
import com.gvmax.common.util.MiscUtils;
import com.gvmax.common.util.NetUtil;
public class XmppInServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger(XmppInServlet.class.getName());
private static final String SERVER_URL = Config.GVMAX_HOST + "/api/xmppIn";
// private static final String serverUrl =
// "https://naguib.homeip.net/gvmax/rpc/xmppIn";
private static final AtomicLong COUNTER = new AtomicLong();
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
XMPPService xmpp = XMPPServiceFactory.getXMPPService();
Message message = null;
try {
message = xmpp.parseMessage(req);
} catch (Exception e) {
logger.warning("Received invalid xmpp message: " + e.getMessage());
return;
}
if (message == null) {
logger.warning("Received null xmpp message");
return;
}
// Prepare message
String reqId = this + "-" + COUNTER.incrementAndGet();
String from = message.getFromJid().toString();
String[] to = new String[message.getRecipientJids().length];
for (int x = 0; x < to.length; x++) {
to[x] = message.getRecipientJids()[x].toString();
}
String msg = message.getBody();
// Clear pidgin bug
msg = msg.replaceAll("\\\\u0009 \\\\u0009\\\\u0009\\\\u0009\\\\u0009 \\\\u0009 \\\\u0009 \\\\u0009 \\\\u0009 \\\\u0009 \\\\u0009 \\\\u0009\\\\u0009 \\\\u0009", "");
msg = msg.replaceAll("\\u0009 \\u0009\\u0009\\u0009\\u0009 \\u0009 \\u0009 \\u0009 \\u0009 \\u0009 \\u0009 \\u0009\\u0009 \\u0009", "");
Map<String, String> params = new HashMap<String, String>();
Enc enc = new Enc(Config.ENC_KEY, 128);
params.put("reqId", enc.encrypt(reqId));
params.put("from", enc.encrypt(from));
params.put("to", enc.encrypt(toString(to)));
params.put("msg", enc.encrypt(msg));
// Send message
Exception exception = null;
int retryCount = 0;
while (retryCount < 3) {
try {
NetUtil.doPost(SERVER_URL, params);
logger.info("xmpp message sent to server from " + from);
return;
} catch (Exception e) {
exception = e;
retryCount += 1;
logger.warning(e.getMessage());
try {
Thread.sleep(retryCount * 1000);
} catch (InterruptedException ie) {
MiscUtils.emptyBlock();
}
}
}
logger.severe("Failed to talk to " + SERVER_URL + " : " + exception.getMessage());
try {
Message emsg = new MessageBuilder().withFromJid(message.getRecipientJids()[0]).withRecipientJids(message.getFromJid()).withBody("unable to contact gvmax: " + exception.getMessage()).build();
xmpp.sendMessage(emsg);
} catch (Exception e) {
logger.severe("Unable to send error message : " + e.getMessage());
}
}
private static String toString(String[] values) {
if (values == null || values.length == 0) {
return "";
}
StringBuffer buffer = new StringBuffer();
for (String value : values) {
buffer.append(value);
buffer.append(",");
}
String retVal = buffer.toString();
return retVal.substring(0, retVal.length() - 1);
}
}