views:

1285

answers:

1

I am getting "104Incorrect signature " . What should I be setting contentType type as? Should I set as:

String contentType = "application/x-www-form-urlencoded";

or

String contentType = "multipart/form-data; boundary=" + kStringBoundary;

This is how I am writing the stream:

HttpURLConnection conn = null; OutputStream out = null; InputStream in = null; try { conn = (HttpURLConnection) _loadingURL.openConnection(); conn.setDoOutput(true); conn.setDoInput(true);

        if (method != null) {
            conn.setRequestMethod(method);
            if ("POST".equals(method)) {
                //"application/x-www-form-urlencoded";
                String contentType = "multipart/form-data; boundary=" + kStringBoundary;
                //String contentType = "application/x-www-form-urlencoded";
                conn.setRequestProperty("Content-Type", contentType);
            }

            // Cookies are used in FBPermissionDialog and FBFeedDialog to
            // retrieve logged user

            conn.connect();

            out = conn.getOutputStream();
            if ("POST".equals(method)) {
                String body = generatePostBody(postParams);
                if (body != null) {
                    out.write(body.getBytes("UTF-8"));
                }
            }
            in = conn.getInputStream();

Here's the method I am using to publish the stream:

private void publishFeed(String themessage) { //Intent intent = new Intent(this, FBFeedActivity.class); // intent.putExtra("userMessagePrompt", themessage); // intent.putExtra("attachment", Map getParams = new HashMap(); // getParams.put("display", "touch"); // getParams.put("callback", "fbconnect://success"); // getParams.put("cancel", "fbconnect://cancel");

     Map<String, String> postParams = new HashMap<String, String>();

     postParams.put("api_key", _session.getApiKey());
     postParams.put("method", "stream.publish");
     postParams.put("session_key", _session.getSessionKey());
     postParams.put("user_message", "TESTING 123");
    // postParams.put("preview", "1");
     postParams.put("attachment", "{\"name\":\"Facebook Connect for Android\",\"href\":\"http://code.google.com/p/fbconnect-android/\",\"caption\":\"Caption\",\"description\":\"Description\",\"media\":[{\"type\":\"image\",\"src\":\"http://img40.yfrog.com/img40/5914/iphoneconnectbtn.jpg\",\"href\":\"http://developers.facebook.com/connect.php?tab=iphone/\"}],\"properties\":{\"another link\":{\"text\":\"Facebook home page\",\"href\":\"http://www.facebook.com\"}}}");
    // postParams.put("user_message_prompt", "22222");


     try {
         loadURL("http://api.facebook.com/restserver.php", "POST", getParams, postParams);
     } catch (MalformedURLException e) {
         e.printStackTrace();
     }
}

Here is generatePostBody() :

private String generatePostBody(Map params) { StringBuilder body = new StringBuilder(); StringBuilder endLine = new StringBuilder("\r\n--").append(kStringBoundary).append("\r\n");

    body.append("--").append(kStringBoundary).append("\r\n");

    for (Entry<String, String> entry : params.entrySet()) {
        body.append("Content-Disposition: form-data; name=\"").append(entry.getKey()).append("\"\r\n\r\n");
        String value = entry.getValue();
        if ("user_message_prompt".equals(entry.getKey())) {
            body.append(value);
        }
        else {
            body.append(CcUtil.encode(value));
        }

        body.append(endLine);
    }

    return body.toString();
}

THANKS

A: 

This is from Facebook Developers Wiki: http://wiki.developers.facebook.com/index.php/API

Note: If you manually form your HTTP POST requests to Facebook, you must include the request data in the POST body. In addition, you should include a Content-Type: header of application/x-www-form-urlencoded.

Use multipart/form-data when uploading files only (e.g. Photos.upload on Facebook API)

Also, Based on this API reference, http://wiki.developers.facebook.com/index.php/How_Facebook_Authenticates_Your_Application, this is what you're doing wrong.

1) Don't use HashMap to store Facebook parameters. Parameters must be sorted by their key. Rather use SortedMap interface and use TreeMap to store Facebook parameters.

2) Always include the sig parameter in the map before sending the call to Facebook. You're getting a "104 Incorrect signature" because Facebook doesn't find the sig parameter in your request.

The reference (http://wiki.developers.facebook.com/index.php/How_Facebook_Authenticates_Your_Application) shows exactly how to create a MD5 signature which facebook uses.

Here's how to quickly create a sig value for Facebook.

String hashString = "";
        Map<String, String> sortedMap = null;
        if (parameters instanceof TreeMap) {
            sortedMap = (TreeMap<String, String>) parameters; 
        } else {
            sortedMap = new TreeMap<String, String>(parameters);
        }

        try {
            Iterator<String> iter = sortedMap.keySet().iterator();
            StringBuilder sb = new StringBuilder();
            synchronized (iter) {
                while (iter.hasNext()) {
                    String key = iter.next();
                    sb.append(key);
                    sb.append("=");
                    String value = sortedMap.get(key);
                    sb.append(value == null ? "" : value);
                }
            }
            sb.append(secret);

            MessageDigest digest = MessageDigest.getInstance("MD5");
            byte[] digested = digest.digest(sb.toString().getBytes());

            BigInteger bigInt = new BigInteger(1, digested);
            hashString = bigInt.toString(16);
            while (hashString.length() < 32) {
                hashString = "0" + hashString;
            }
        } catch (NoSuchAlgorithmException nsae) {
            // TODO: handle exception
            logger.error(e.getLocalizedMessage(), e);
        }

        return hashString;
The Elite Gentleman