blob: 4cfb8f107a05a100ae2c27d009a4c3b378a017b9 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. The ASF licenses this file to You
* under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License. For additional information regarding
* copyright in this work, please see the NOTICE file in the top level
* directory of this distribution.
*/
package org.apache.roller.weblogger.util;
import java.io.IOException;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.roller.util.RollerConstants;
import org.apache.roller.weblogger.WebloggerException;
import org.apache.roller.weblogger.config.WebloggerConfig;
import org.apache.roller.weblogger.pojos.WeblogEntry;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
/**
* Represents a trackback request.
*/
public class Trackback {
private static final Log LOG = LogFactory.getLog(Trackback.class);
private final WeblogEntry entry;
private final String trackbackURL;
public Trackback(WeblogEntry tEntry, String tURL)
throws TrackbackNotAllowedException {
// Make sure trackback to URL is allowed
boolean allowTrackback = true;
String allowedURLs = WebloggerConfig.getProperty("trackback.allowedURLs");
if (!StringUtils.isEmpty(allowedURLs)) {
// in the case that the administrator has enabled trackbacks
// for only specific URLs, set it to false by default
allowTrackback = false;
String[] splitURLs = allowedURLs.split("\\|\\|");
for (int i=0; i < splitURLs.length; i++) {
Matcher m = Pattern.compile(splitURLs[i]).matcher(tURL);
if (m.matches()) {
allowTrackback = true;
break;
}
}
}
if(!allowTrackback) {
throw new TrackbackNotAllowedException(tURL);
} else {
// test url
try {
new URL(tURL);
} catch(MalformedURLException ex) {
// bad url
throw new IllegalArgumentException("bad url: "+tURL);
}
entry = tEntry;
trackbackURL = tURL;
}
}
/**
* Sends trackback from entry to remote URL.
* See Trackback spec for details: http://www.sixapart.com/pronet/docs/trackback_spec
*/
public RollerMessages send() throws WebloggerException {
RollerMessages messages = new RollerMessages();
LOG.debug("Sending trackback to url - " + trackbackURL);
// Construct data
String title = entry.getTitle();
String excerpt = StringUtils.left( Utilities.removeHTML(entry.getDisplayContent()),
RollerConstants.TEXTWIDTH_255);
String url = entry.getPermalink();
String blog_name = entry.getWebsite().getName();
// build trackback post parameters as query string
Map params = new HashMap();
params.put("title", URLUtilities.encode(title));
params.put("excerpt", URLUtilities.encode(excerpt));
params.put("url", URLUtilities.encode(url));
params.put("blog_name", URLUtilities.encode(blog_name));
String queryString = URLUtilities.getQueryString(params);
LOG.debug("query string - " + queryString);
// prepare http request
HttpClient client = new HttpClient();
client.setConnectionTimeout(45 * RollerConstants.SEC_IN_MS);
HttpMethod method = new PostMethod(trackbackURL);
method.setQueryString(queryString);
try {
// execute trackback
int statusCode = client.executeMethod(method);
// read response
byte[] response = method.getResponseBody();
String responseString = Utilities.escapeHTML(new String(response, "UTF-8"));
LOG.debug("result = " + statusCode + " " + method.getStatusText());
LOG.debug("response:\n" + responseString);
if(statusCode == HttpStatus.SC_OK) {
// trackback request succeeded, message will give details
try {
messages = parseTrackbackResponse(new String(response, "UTF-8"), messages);
} catch (Exception e) {
// Cannot parse response, indicates failure
messages.addError("weblogEdit.trackbackErrorParsing", responseString);
}
} else if(statusCode == HttpStatus.SC_NOT_FOUND) {
// 404, invalid trackback url
messages.addError("weblogEdit.trackbackError404");
} else {
// some other kind of error with url, like 500, 403, etc
// just provide a generic error message and give the http response text
messages.addError("weblogEdit.trackbackErrorResponse",
new String[] {""+statusCode, method.getStatusText()});
}
} catch (IOException e) {
// some kind of transport error sending trackback post
LOG.debug("Error sending trackback", e);
messages.addError("weblogEdit.trackbackErrorTransport");
} finally {
// release used connection
method.releaseConnection();
}
return messages;
}
/**
* Parse XML returned from trackback POST, returns error or success message
* in RollerMessages object.
*/
private RollerMessages parseTrackbackResponse(String response, RollerMessages messages)
throws JDOMException, IOException {
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(
new StringReader(StringEscapeUtils.unescapeHtml4(response)));
Element root = doc.getRootElement();
if ("response".equals(root.getName())) {
int code = -99;
try {
code = Integer.parseInt(root.getChildText("error"));
} catch (NumberFormatException ignoredByDesign) {}
String message = root.getChildText("message");
if (code != 0) {
messages.addError("weblogEdit.trackbackFailure", Utilities.removeHTML(message));
} else {
messages.addMessage("weblogEdit.trackbackSuccess");
}
} else {
messages.addError("weblogEdit.trackbackErrorParsing", Utilities.removeHTML(response));
}
return messages;
}
}