Urlencode POST to conduit Phabricator API expects POST be urlencoded, much like when a browser submit a form (Content-Type: x-www-form-urlencoded) with the payload being urlencoded. As an example, when doing a `maniphest.edit` to add a comment containing 'http://example.org/r/+/1234', the content is send as is but urldecoded by Phabricator which show with: 'http://example.org/r/ /1234', the '+' has been decoded to a space. We previously encountered the issue with commit message which we escapes in the soy template: ${escapedSubject|escapeUri} which is merely a workaround. Some support request got send previously at: https://github.com/google/closure-templates/issues/152 which missed the lack of urlencoding in the POST. Instead of sending a StringEntity with 'param=<json>', use a UrlEncodedFormEntity which takes care of encoding. Soy templates can then drop usage of `escapeUri`. Bug: https://phabricator.wikimedia.org/T280197 Change-Id: Icee02a62853817ecaa73403c44ce557634ecb07e
diff --git a/src/main/java/com/googlesource/gerrit/plugins/its/phabricator/conduit/ConduitConnection.java b/src/main/java/com/googlesource/gerrit/plugins/its/phabricator/conduit/ConduitConnection.java index 8eb695b..585cd3b 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/its/phabricator/conduit/ConduitConnection.java +++ b/src/main/java/com/googlesource/gerrit/plugins/its/phabricator/conduit/ConduitConnection.java
@@ -22,14 +22,18 @@ import com.googlesource.gerrit.plugins.its.phabricator.conduit.results.CallCapsule; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.apache.http.HttpEntity; +import org.apache.http.NameValuePair; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; +import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; /** Abstracts the connection to Conduit API */ @@ -101,7 +105,10 @@ String json = gson.toJson(params); logger.atFinest().log("Calling phabricator method %s with the parameters %s", method, json); - httppost.setEntity(new StringEntity("params=" + json, StandardCharsets.UTF_8)); + + List<NameValuePair> values = new ArrayList<NameValuePair>(); + values.add(new BasicNameValuePair("params", json)); + httppost.setEntity(new UrlEncodedFormEntity(values, StandardCharsets.UTF_8)); try (CloseableHttpResponse response = getClient().execute(httppost)) { logger.atFinest().log("Phabricator HTTP response status: %s", response.getStatusLine());