Twitter.java
/*
* Twitter.java
*
* Author: Markku Rossi <mtr@iki.fi>
*
* Copyright (c) 2011-2012, Markku Rossi
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
* * Neither the name of the Markku Rossi nor the names of its
* contributors may be used to endorse or promote products
* derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
import java.io.*;
import java.net.*;
import java.security.SignatureException;
import java.security.SecureRandom;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class Twitter
{
private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";
private static final String BASE64
= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
public static String base64Encode(byte[] data)
{
StringBuilder sb = new StringBuilder();
int i, len;
for (i = 0, len = data.length; len > 0; i += 3, len -= 3)
{
int val;
val = (data[i] & 0xff) << 16;
if (len > 1)
val |= (data[i + 1] & 0xff) << 8;
if (len > 2)
val |= (data[i + 2] & 0xff);
sb.append(BASE64.charAt(val >> 18));
sb.append(BASE64.charAt((val >> 12) & 0x3f));
sb.append(BASE64.charAt((val >> 6) & 0x3f));
sb.append(BASE64.charAt(val & 0x3f));
}
for (; len < 0; len++)
sb.setCharAt(sb.length() + len, '=');
return sb.toString();
}
private static String urlEncode(String s)
{
StringBuilder sb = new StringBuilder();
int i;
for (i = 0;i < s.length(); i++)
{
char ch = s.charAt(i);
if ('0' <= ch && ch <= '9'
|| 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z'
|| ch == '-' || ch == '.' || ch == '_' || ch == '~')
{
sb.append(ch);
}
else
{
int val = (int) ch & 0xff;
sb.append('%');
if (val <= 0xf)
sb.append('0');
sb.append(Integer.toHexString(val).toUpperCase());
}
}
return sb.toString();
}
private static final String CONSUMER_KEY
= "*** consumer key ***";
private static final String CONSUMER_SECRET
= "*** consumer secret ***********************";
private static final String TOKEN
= "*** access token *********************************";
private static final String TOKEN_SECRET
= "*** token secret *************************";
private static final String MAC_NAME = "HmacSHA1";
/** Random nonce. */
private static String nonce;
/** Current unix time in seconds. */
private static long timestamp;
private static void addParam(StringBuilder sb, boolean first,
String key, String value)
{
if (!first)
sb.append("%26");
sb.append(urlEncode(key));
sb.append("%3D");
sb.append(urlEncode(value));
}
private static String computeAuthorization(String message,
String url,
String method,
String consumerKey,
String consumerSecret,
String token,
String tokenSecret)
{
try
{
String keyString = (urlEncode(consumerSecret)
+ "&" + urlEncode(tokenSecret));
byte[] keyBytes = keyString.getBytes("UTF-8");
SecretKeySpec key = new SecretKeySpec(keyBytes, MAC_NAME);
Mac mac = Mac.getInstance(MAC_NAME);
mac.init(key);
StringBuilder sbs = new StringBuilder();
sbs.append(method);
sbs.append("&");
sbs.append(urlEncode(url));
sbs.append("&");
addParam(sbs, true, "oauth_consumer_key", consumerKey);
addParam(sbs, false, "oauth_nonce", nonce);
addParam(sbs, false, "oauth_signature_method", "HMAC-SHA1");
addParam(sbs, false, "oauth_timestamp", String.valueOf(timestamp));
addParam(sbs, false, "oauth_token", token);
addParam(sbs, false, "oauth_version", "1.0");
addParam(sbs, false, "status", urlEncode(message));
System.out.println("SBS: " + sbs.toString());
byte[] text = sbs.toString().getBytes("UTF-8");
return base64Encode(mac.doFinal(text));
}
catch (Throwable t)
{
t.printStackTrace();
return null;
}
}
private static void twitterPost(String message, String baseUrl, String method,
String consumerKey, String consumerSecret,
String token, String tokenSecret)
{
int i;
/* Create nonce. */
StringBuilder nb = new StringBuilder();
SecureRandom random = new SecureRandom();
for (i = 0; i < 20; i++)
nb.append(Integer.toHexString(random.nextInt(256)));
nonce = nb.toString();
/* Time in seconds. */
timestamp = System.currentTimeMillis() / 1000;
String signature = computeAuthorization(message, baseUrl, method,
consumerKey, consumerSecret,
token, tokenSecret);
StringBuilder sb = new StringBuilder();
sb.append("OAuth");
sb.append(" oauth_consumer_key=\"");
sb.append(urlEncode(consumerKey));
sb.append("\",oauth_signature_method=\"");
sb.append("HMAC-SHA1");
sb.append("\",oauth_timestamp=\"");
sb.append(String.valueOf(timestamp));
sb.append("\",oauth_nonce=\"");
sb.append(urlEncode(nonce));
sb.append("\",oauth_version=\"");
sb.append(urlEncode("1.0"));
sb.append("\",oauth_token=\"");
sb.append(urlEncode(token));
sb.append("\",oauth_signature=\"");
sb.append(urlEncode(signature));
sb.append("\"");
System.out.println("Authorization: " + sb.toString());
HttpURLConnection conn = null;
try
{
URL url = new URL(baseUrl);
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod(method);
StringBuilder cb = new StringBuilder();
cb.append(urlEncode("status"));
cb.append("=");
cb.append(urlEncode(message));
String contentString = cb.toString();
System.out.println("content: " + contentString);
byte[] content = contentString.getBytes("UTF-8");
conn.setRequestProperty("Authorization", sb.toString());
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length",
Integer.toString(content.length));
OutputStream os = conn.getOutputStream();
os.write(content);
os.close();
int responseCode = conn.getResponseCode();
System.out.println("code=" + responseCode);
InputStream is;
try
{
is = conn.getInputStream();
}
catch (IOException e)
{
is = conn.getErrorStream();
}
InputStreamReader isr = new InputStreamReader(is);
int ch;
while ((ch = isr.read()) >= 0)
System.out.write((char) ch);
isr.close();
System.out.println();
}
catch (Throwable t)
{
t.printStackTrace();
}
finally
{
if (conn != null)
conn.disconnect();
}
}
public static void main(String argv[])
{
twitterPost(argv[0],
"http://api.twitter.com/1/statuses/update.json",
"POST",
CONSUMER_KEY, CONSUMER_SECRET, TOKEN, TOKEN_SECRET);
}
}
Generated by GNU enscript 1.6.4.