diff -up ../shorturl.orig/shorturl.module ./shorturl.module
--- ../shorturl.orig/shorturl.module	2010-04-19 15:01:49.000000000 +0200
+++ ./shorturl.module	2010-04-19 17:20:57.000000000 +0200
@@ -90,4 +90,98 @@ function shorturl_reserved_tokens() {
   $reserved_system = array('node', 'admin', 'term', 'user');
   
   return $reserved_system + $reserved_settings;
+}
+
+/**
+ * Implements hook_perm().
+ */
+function shorturl_perm() {
+  return array('use shorturl');
+}
+
+/**
+ * Implements hook_menu().
+ */
+function shorturl_menu() {
+  $menu = array();
+  $menu['v1/shorten'] = array(
+    'page callback' => 'shorturl_rest_shorten',
+    'access callback' => 'shorturl_menu_access',
+  );
+  return $menu;
+}
+
+/**
+ * Menu access callback
+ */
+function shorturl_menu_access() {
+  return TRUE;
+}
+
+/**
+ * Menu callback
+ */
+function shorturl_rest_shorten() {
+  foreach (array('username', 'password', 'uri') as $varname) {
+    if (empty($_GET[$varname])) {
+      shorturl_rest_respond(500, "Missing $varname argument");
+    }
+  }
+  if (!valid_url($_GET['uri'], TRUE)) {
+    shorturl_rest_respond(500, 'Invalid URI');
+  }
+  if (!$account = user_load(array('name' => $_GET['username'], 'pass' => $_GET['password']))) {
+    shorturl_rest_respond(401, 'Invalid credentials');
+  }
+  if (!user_access('use shorturl', $account)) {
+    shorturl_rest_respond(403, 'Permission denied');
+  }
+  shorturl_rest_respond(200, 'OK', array(
+    'url' => 'http://' . $_SERVER['HTTP_HOST'] . url(shorturl_shorten($_REQUEST['uri'])),
+    'long_url' => $_REQUEST['uri'],
+  ));
+}
+
+/**
+ * Send REST response to the user
+ */
+function shorturl_rest_respond($code, $txt, $data = array()) {
+  switch ($code) {
+    case 500:
+      header('HTTP/1.0 500 Internal Server Error');
+      break;
+    case 401:
+      header('HTTP/1.0 401 Unauthorized');
+      break;
+    case 403:
+      header('HTTP/1.0 403 Forbidden');
+      break;
+  }
+  $format = empty($_GET['format']) ? 'json' : $_GET['format'];
+  switch ($format) {
+    case 'txt':
+      header('Content-Type: text/plain');
+      print $code == 200 ? $data['url'] : $txt;
+      break;
+    case 'xml':
+      header('Content-Type: text/xml');
+      print format_xml_elements(array(
+        'response' => array(
+          'status_code' => $code,
+          'status_txt' => $txt,
+          'data' => $data,
+        ),
+      ));
+      break;
+    default:
+      header('Content-Type: application/json');
+      print drupal_json(array(
+        'status_code' => $code,
+        'status_txt' => $txt,
+        'data' => $data,
+      ));
+      break;
+  }
+  module_invoke_all('exit');
+  exit;
 }
\ No newline at end of file
Only in ./: shorturl_rest.patch
