Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Web and WebWorks Development

Reply
Contributor
Posts: 21
Registered: ‎12-03-2010
My Device: Blackberry Bold 9700

JavaScript Extension to be able to use Basic Authentication ( on OS <6)

Hi,

 

I've noticed that AJAX with Basic Authentication through headers actually works for OS 6 devices, but I can't get them to work on OS 5.x.x.xxx:

.ajax( {
                url : '<my_url>'
                cache : false,
                type : 'POST',
                data : "<my_data>",
                beforeSend : function(xhr) {
                    xhr.setRequestHeader("Authentication",
                            "Basic <my_auth_string>");
                },

                dataType : "json",
                success : onSuccess,
                error : onError
            });

With the above code I can authenticate using jquery 1.4.4 on devices like Tourch but it won't work on Bold with OS 5.

 

To solve this I've created an JavaScript Ext that authenticates and returns the result as a callback. The code that I'm using to grab the URL content and returning it, is below (I will not post the entire code to be more readable):

public class MyFunction extends ScriptableFunction {

    public Object invoke(Object thiz, Object[] args) throws Exception {

        ScriptableFunction _callback = null;
        ScriptableFunction _error = null;
        final UiApplication uiApp = UiApplication.getUiApplication();

        String url = null;
        try {

            Scriptable config = (Scriptable) args[0];
            _callback = (ScriptableFunction) config.getField("success");
            url = (String) config.getField("url");
            String data = null;
            String type = null;

            if (config.getField("error") != null) {
                _error = (ScriptableFunction) config.getField("error");
            }
            if (config.getField("type") != null) {
                type = (String) config.getField("type");
            }
            if (config.getField("data") != null) {
                data = (String) config.getField("data");
            }

            uiApp.invokeLater(new AJAXRunnable(url, data, type, _callback,
                    _error));
        } catch (Exception e) {
            if (_error != null) {
                final Object[] threadedResult = new Object[1];
                threadedResult[0] = e.getMessage();
                final ScriptableFunction threadedError = _error;
                new Thread() {
                    public void run() {
                        try {
                            threadedError.invoke(threadedError, threadedResult);
                        } catch (Exception e) {
                            throw new RuntimeException(e.getMessage());
                        }
                    }
                }.start();
            }
        }

        return UNDEFINED;
    }

    private class AJAXRunnable implements Runnable {
        private ScriptableFunction _callback = null;
        private ScriptableFunction _error = null;
        private String _url = null;
        private String _data = null;
        private String _type = null;
        private HttpConnection httpConn = null;
        private StreamConnection s = null;
        private StringBuffer raw = new StringBuffer();
        private InputStream contentIn = null;
        private OutputStream output = null;

        public AJAXRunnable(String url, String data, String type,
                ScriptableFunction callback, ScriptableFunction error) {

            _callback = callback;
            _type = type;
            _url = url;
            _data = data;
            _error = error;
        }

        public void run() {
            try {
                String suffix = ConnectionCreator.getConnectionString();

                s = (StreamConnection) Connector.open(_url + suffix,
                        Connector.WRITE, true);
                httpConn = (HttpConnection) s;

                httpConn.setRequestProperty("User-Agent", "BlackBerry Client");
                httpConn.setRequestProperty("Accept", "*/*");
                httpConn.setRequestProperty("Content-Type",
                        "application/x-www-form-urlencoded");

                httpConn.setRequestMethod(_type);
                httpConn.setRequestProperty(
                        HttpProtocolConstants.HEADER_AUTHORIZATION,
                        "Basic <my_auth_string>");

                if ((_data != null) && (_data.length() > 0)) {

                    byte[] postdata = _data.getBytes("UTF-8");
                    httpConn.setRequestProperty("Content-Length", Integer
                            .toString(postdata.length));
                    output = httpConn.openOutputStream();
                    output.write(postdata);
                }
                int status = httpConn.getResponseCode();
                if (status == HttpConnection.HTTP_UNAUTHORIZED) {
                    s.close();
                    s = (StreamConnection) Connector.open(_url + suffix,
                            Connector.WRITE, true);
                    httpConn = (HttpConnection) s;

                    httpConn.setRequestProperty("User-Agent",
                            "BlackBerry Client");
                    httpConn.setRequestProperty("Accept", "*/*");
                    httpConn.setRequestProperty("Content-Type",
                            "application/x-www-form-urlencoded");

                    httpConn.setRequestMethod(_type);
                    httpConn.setRequestProperty(
                            HttpProtocolConstants.HEADER_AUTHORIZATION,
                            "Basic <my_auth_string>");

                    if ((_data != null) && (_data.length() > 0)) {

                        byte[] postdata = _data.getBytes("UTF-8");
                        httpConn.setRequestProperty("Content-Length", Integer
                                .toString(postdata.length));
                        output = httpConn.openOutputStream();
                        output.write(postdata);

                    }
                }
                status = httpConn.getResponseCode();

                contentIn = s.openInputStream();
                byte[] data = new byte[4096];
                int length = 0;

                while (-1 != (length = contentIn.read(data))) {
                    raw.append(new String(data, 0, length));
                }
                if (contentIn != null) {
                    try {
                        contentIn.close();
                    } catch (Exception ignored) {
                    }
                }
                if (output != null) {
                    try {
                        output.close();
                    } catch (Exception ignored) {
                    }
                }
                if (httpConn != null) {
                    try {
                        httpConn.close();
                    } catch (Exception ignored) {
                    }
                }
                s.close();
                final Object[] threadedResult = new Object[1];
                threadedResult[0] = raw.toString();
                new Thread() {
                    public void run() {
                        try {
                            _callback.invoke(_callback, threadedResult);
                        } catch (Exception e) {
                            throw new RuntimeException(e.getMessage());
                        }
                    }
                }.start();
            } catch (IOException e) {
                if (_error != null) {
                    final Object[] threadedResult = new Object[1];
                    threadedResult[0] = e.getMessage();
                    new Thread() {
                        public void run() {
                            try {
                                _error.invoke(_error, threadedResult);
                            } catch (Exception e) {
                                throw new RuntimeException(e.getMessage());
                            }
                        }
                    }.start();
                }
            } finally {
                if (contentIn != null) {
                    try {
                        contentIn.close();
                    } catch (Exception ignored) {
                    }
                }
                if (output != null) {
                    try {
                        output.close();
                    } catch (Exception ignored) {
                    }
                }
                if (httpConn != null) {
                    try {
                        httpConn.close();
                    } catch (Exception ignored) {
                    }
                }
            }
        }

    }

}

 

With the code above I actually can authenticate using devices with OS 5, but there's a problem:

- Even though I use the "uiApp.invokeLater" the widget application hangs until it fetches the entire url content and only then it returns to the widget.

This is acceptable if the URL content is small, but when the content has more than 100KB the widget just becomes unusable until it loads the URL.

 

Can anyone point me in the right direction to solve this issue?

 

Best regards,

Daniel Botelho