HttpAuthHandler.java revision 105925376f8d0f6b318c9938c7b83ef7fef094da
1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.webkit;
18
19import android.os.Bundle;
20import android.os.Handler;
21import android.os.Message;
22
23import java.util.ListIterator;
24import java.util.LinkedList;
25
26/**
27 * HTTP authentication handler: local handler that takes care
28 * of HTTP authentication requests. This class is passed as a
29 * parameter to BrowserCallback.displayHttpAuthDialog and is
30 * meant to receive the user's response.
31 */
32public class HttpAuthHandler extends Handler {
33    /* It is important that the handler is in Network, because
34     * we want to share it accross multiple loaders and windows
35     * (like our subwindow and the main window).
36     */
37
38    private static final String LOGTAG = "network";
39
40    /**
41     * Network.
42     */
43    private Network mNetwork;
44
45    /**
46     * Loader queue.
47     */
48    private LinkedList<LoadListener> mLoaderQueue;
49
50
51    // Message id for handling the user response
52    private final int AUTH_PROCEED = 100;
53    private final int AUTH_CANCEL = 200;
54
55    /**
56     * Creates a new HTTP authentication handler with an empty
57     * loader queue
58     *
59     * @param network The parent network object
60     */
61    /* package */ HttpAuthHandler(Network network) {
62        mNetwork = network;
63        mLoaderQueue = new LinkedList<LoadListener>();
64    }
65
66
67    @Override
68    public void handleMessage(Message msg) {
69        LoadListener loader = null;
70        synchronized (mLoaderQueue) {
71            loader = mLoaderQueue.poll();
72        }
73
74        switch (msg.what) {
75            case AUTH_PROCEED:
76                String username = msg.getData().getString("username");
77                String password = msg.getData().getString("password");
78
79                loader.handleAuthResponse(username, password);
80                break;
81
82            case AUTH_CANCEL:
83                loader.handleAuthResponse(null, null);
84                break;
85        }
86
87        processNextLoader();
88    }
89
90
91    /**
92     * Proceed with the authorization with the given credentials
93     *
94     * @param username The username to use for authentication
95     * @param password The password to use for authentication
96     */
97    public void proceed(String username, String password) {
98        Message msg = obtainMessage(AUTH_PROCEED);
99        msg.getData().putString("username", username);
100        msg.getData().putString("password", password);
101        sendMessage(msg);
102    }
103
104    /**
105     * Cancel the authorization request
106     */
107    public void cancel() {
108        sendMessage(obtainMessage(AUTH_CANCEL));
109    }
110
111    /**
112     * @return True if we can use user credentials on record
113     * (ie, if we did not fail trying to use them last time)
114     */
115    public boolean useHttpAuthUsernamePassword() {
116        LoadListener loader = null;
117        synchronized (mLoaderQueue) {
118            loader = mLoaderQueue.peek();
119        }
120        if (loader != null) {
121            return !loader.authCredentialsInvalid();
122        }
123
124        return false;
125    }
126
127    /**
128     * Enqueues the loader, if the loader is the only element
129     * in the queue, starts processing the loader
130     *
131     * @param loader The loader that resulted in this http
132     * authentication request
133     */
134    /* package */ void handleAuthRequest(LoadListener loader) {
135        boolean processNext = false;
136
137        synchronized (mLoaderQueue) {
138            mLoaderQueue.offer(loader);
139            processNext =
140                (mLoaderQueue.size() == 1);
141        }
142
143        if (processNext) {
144            processNextLoader();
145        }
146    }
147
148    /**
149     * Process the next loader in the queue (helper method)
150     */
151    private void processNextLoader() {
152        LoadListener loader = null;
153        synchronized (mLoaderQueue) {
154            loader = mLoaderQueue.peek();
155        }
156        if (loader != null) {
157            CallbackProxy proxy = loader.getFrame().getCallbackProxy();
158
159            String hostname = loader.proxyAuthenticate() ?
160                mNetwork.getProxyHostname() : loader.host();
161
162            String realm = loader.realm();
163
164            proxy.onReceivedHttpAuthRequest(this, hostname, realm);
165        }
166    }
167}
168