// Copyright 2011 Google Inc. All Rights Reserved. package info.persistent.pushbot; import com.google.appengine.api.utils.HttpRequestParser; import com.google.appengine.api.xmpp.JID; import info.persistent.pushbot.data.XmppError; import info.persistent.pushbot.util.Persistence; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import javax.jdo.PersistenceManager; import javax.mail.BodyPart; import javax.mail.MessagingException; import javax.mail.internet.MimeMultipart; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @SuppressWarnings("serial") public class XmppErrorServlet extends HttpServlet { // TODO(mihaip): switch to Error and InboundErrorParser once they're available. private class Error { private final JID from; private final JID to; private final String body; private final String stanza; public Error(JID from, JID to, String body, String stanza) { this.from = from; this.to = to; this.body = body; this.stanza = stanza; } @Override public String toString() { String response = ""; if (from != null) { response += "from: " + from + "\n"; } if (to != null) { response += "to: " + to + "\n"; } if (body != null) { response += "body: " + body + "\n"; } if (stanza != null) { response += "stanza: " + stanza + "\n"; } return response; } } private class ErrorParser extends HttpRequestParser { private Error parse(HttpServletRequest req) throws IOException { try { MimeMultipart multipart = parseMultipartRequest(req); JID from = null; JID to = null; String body = null; String stanza = null; for (int i = 0; i < multipart.getCount(); i++) { BodyPart part = multipart.getBodyPart(i); String fieldName = getFieldName(part); if ("from".equals(fieldName)) { from = new JID(getTextContent(part)); } else if ("to".equals(fieldName)) { to = new JID(getTextContent(part)); } else if ("body".equals(fieldName)) { body = getTextContent(part); } else if ("stanza".equals(fieldName)) { stanza = getTextContent(part); } } return new Error(from, to, body, stanza); } catch (MessagingException err) { logger.log(Level.WARNING, "Could not parse error request", err); return null; } } } public static final Logger logger = Logger.getLogger(XmppErrorServlet.class.getName()); @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { Error error = new ErrorParser().parse(req); if (error != null) { logger.info("XMPP error: " + error); if (error.from != null) { final XmppError xmppError = XmppError.getOrCreateForUser(error.from); xmppError.incrementErrorCount(); logger.info(error.from.getId() + " now has " + xmppError.getErrorCount() + " errors"); Persistence.withManager(new Persistence.Closure() { @Override public void run(PersistenceManager manager) { manager.makePersistent(xmppError); } }); } resp.getWriter().write("OK"); } else { resp.sendError(HttpServletResponse.SC_BAD_REQUEST); } } }