blob: 206959980355771186eea7d14d35ec5d4c41a4c3 [file] [log] [blame]
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.webkit;
import android.net.http.Headers;
import java.io.InputStream;
import java.util.*;
import org.apache.http.util.CharArrayBuffer;
/**
* This class is a concrete implementation of StreamLoader that uses a
* PluginData object as the source for the stream.
*/
class PluginContentLoader extends StreamLoader {
private PluginData mData; // Content source
/**
* Constructs a PluginDataLoader for use when loading content from
* a plugin.
*
* @param loadListener LoadListener to pass the content to
* @param data PluginData used as the source for the content.
*/
PluginContentLoader(LoadListener loadListener, PluginData data) {
super(loadListener);
mData = data;
}
@Override
protected boolean setupStreamAndSendStatus() {
mDataStream = mData.getInputStream();
mContentLength = mData.getContentLength();
mHandler.status(1, 1, mData.getStatusCode(), "OK");
return true;
}
@Override
protected void buildHeaders(Headers headers) {
// Crate a CharArrayBuffer with an arbitrary initial capacity.
CharArrayBuffer buffer = new CharArrayBuffer(100);
Iterator<Map.Entry<String, String[]>> responseHeadersIt =
mData.getHeaders().entrySet().iterator();
while (responseHeadersIt.hasNext()) {
Map.Entry<String, String[]> entry = responseHeadersIt.next();
// Headers.parseHeader() expects lowercase keys, so keys
// such as "Accept-Ranges" will fail to parse.
//
// UrlInterceptHandler instances supply a mapping of
// lowercase key to [ unmodified key, value ], so for
// Headers.parseHeader() to succeed, we need to construct
// a string using the key (i.e. entry.getKey()) and the
// element denoting the header value in the
// [ unmodified key, value ] pair (i.e. entry.getValue()[1).
//
// The reason why UrlInterceptHandler instances supply such a
// mapping in the first place is historical. Early versions of
// the Gears plugin used java.net.HttpURLConnection, which always
// returned headers names as capitalized strings. When these were
// fed back into webkit, they failed to parse.
//
// Mewanwhile, Gears was modified to use Apache HTTP library
// instead, so this design is now obsolete. Changing it however,
// would require changes to the Gears C++ codebase and QA-ing and
// submitting a new binary to the Android tree. Given the
// timelines for the next Android release, we will not do this
// for now.
//
// TODO: fix C++ Gears to remove the need for this
// design.
String keyValue = entry.getKey() + ": " + entry.getValue()[1];
buffer.ensureCapacity(keyValue.length());
buffer.append(keyValue);
// Parse it into the header container.
headers.parseHeader(buffer);
// Clear the buffer
buffer.clear();
}
}
}