[Solved] RPC via Java POST request

Discussion of the Web Interface for Transmission, formerly known as Clutch. This applies to all version of Transmission
Locked
elmotheelk
Posts: 14
Joined: Sat Apr 11, 2009 12:40 am

[Solved] RPC via Java POST request

Post by elmotheelk »

Hi all,

I'm developing a Transmission client based on the RPC protocol. I'm using web POST's with JSON data to communicate. However, I keep getting:
{
"arguments": {},
"result": "no method name"
}

I'm confused, since I am sure I'm sending a name/value pair for both the method and the arguments. Here is a code snippet:

Code: Select all

	
			// Setup request using POST
			httpclient = new DefaultHttpClient();
			if (useAuthentication) {
				httpclient.getCredentialsProvider().setCredentials(
					new AuthScope(address, port), new UsernamePasswordCredentials(username, password));
			}
			HttpPost httppost = new HttpPost(HTTP + address + PORT_DELIMITER + port + PATH_TO_RPC);
			HttpParams params = new BasicHttpParams();
			params.setParameter(RPC_METHOD, method);
			params.setParameter(RPC_ARGUMENTS, data.toString());
			httppost.setParams(params);
			
			// Execute
			HttpResponse response = httpclient.execute(httppost);
			HttpEntity entity = response.getEntity();
			
			if (entity != null) {
				
				// Read JSON response
				InputStream instream = entity.getContent();
				String result = convertStreamToString(instream);
				JSONObject json = new JSONObject(result);
				instream.close();
				
				return json;
				
			}
where 'method' is for example 'torrent-get' and 'data' is the JSON-encoded fields array. Any ideas? Thanks a LOT, in advance.

ElmoTheElk
Last edited by elmotheelk on Wed Apr 15, 2009 1:01 pm, edited 1 time in total.
Jordan
Transmission Developer
Posts: 2312
Joined: Sat May 26, 2007 3:39 pm
Location: Titania's Room

Re: RPC via Java POST request

Post by Jordan »

Hi Elmo,

"transmission-remote --debug" is your friend when you're trying to debug a new RPC request call. What you should do is do a dump of the JSON message that you're POSTingt to the daemon, and compare it with a similar call in "transmission-remote --debug". That's what I do most of the time. :mrgreen:
elmotheelk
Posts: 14
Joined: Sat Apr 11, 2009 12:40 am

Re: RPC via Java POST request

Post by elmotheelk »

Thanks for that tip,

I've looked at the transmission-remote --debug command and it's certainly useful to see what is actually returned. However, in my version (I use the Launchpad PPA 1.51 version) I don't see the request, only the response.

I was thinking, do I need to set some specific encoding type for the http POST request? Or maybe a specific user agent?

The POST has 2 name/value pairs: one is called 'method' and has a value of for example 'torrent-get'. The other is called 'arguments' and has a value of for example '{"fields":["id","name","status","rateDownload","rateUpload","ratio","downloadedEver","uploadedEver","totalSize"]}'. I believe this is right. Of do I need to include the method name inside of the JSON string? Or does the method name itself has to be encoded inside a JSON { } or something?

Actually, I tried to create a tiny little HTML page that uses a form that POSTs the same data to the server. Here is the HTML code:

Code: Select all

<form method="post" action="http://localhost:8080/transmission/rpc">
<input type="text" name="method" value="torrent-get">
<input type="text" name="arguments" value="{ fields: [ "id", "name" ] }">
<input type="submit">
</form>
But I get the exact some JSON response from the daemon: no method name.


Thanks again for any help.
elmotheelk
Posts: 14
Joined: Sat Apr 11, 2009 12:40 am

Re: RPC via Java POST request

Post by elmotheelk »

I solved it!

The problem is that I had to send the JSON object as a stream, not as a name/value pair as used in a BasicHttpEntity. So to stream the JSON string to the server, I needed to use a StringEntity. Here is the fixed code:

Code: Select all

// Setup request using POST
			httpclient = new DefaultHttpClient();
			if (useAuthentication) {
				httpclient.getCredentialsProvider().setCredentials(
					new AuthScope(address, port), new UsernamePasswordCredentials(username, password));
			}
			HttpPost httppost = new HttpPost(HTTP + address + PORT_DELIMITER + port + PATH_TO_RPC);
			StringEntity se = new StringEntity(data.toString());
			httppost.setEntity(se);
			
			// Execute
			HttpResponse response = httpclient.execute(httppost);
			HttpEntity entity = response.getEntity();
			
			if (entity != null) {
				
				// Read JSON response
				InputStream instream = entity.getContent();
				String result = convertStreamToString(instream);
				JSONObject json = new JSONObject(result);
				instream.close();
				
				return json;
				
			}
Thanks for your reaction Jordan, and also very importantly: thanks to Alan (ajf88 on this forum, I believe) for making his .NET-based Transmission remote client for Windows open source. It helped solving this greatly.

If I get a stable release of my software, I'll release it here (open source) of course.
theCrank
Posts: 249
Joined: Sat Jun 28, 2008 8:01 am
Location: Karlsruhe, Germany

Re: [Solved] RPC via Java POST request

Post by theCrank »

It'll be REALLY cool if you could post a message here, so i'll be notified by the forum.
I don't have enough time to keep track of the things going on in the forum. :(
elmotheelk
Posts: 14
Joined: Sat Apr 11, 2009 12:40 am

Re: [Solved] RPC via Java POST request

Post by elmotheelk »

theCrank wrote:It'll be REALLY cool if you could post a message here
About a working Android remote client? Well, it is available for some time now in the Android Market. Also, see the website at http://transdroid.wordpress.com

I do have an issue at this moment related to adding torrents by base64-encoded metadata. I'll open another topic for this.
Locked