📄 kwqloader.cpp
字号:
/*
* Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
* Portions Copyright (c) 2005 Nokia Corporation, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "KWQLoader.h"
#include <e32base.h>
#include "KWQKJobClasses.h"
#include "KWQLogging.h"
#include "KWQResourceLoader.h"
//#include "KWQFoundationExtras.h"
#include "WebCoreBridge.h"
#include "khtml_part.h"
#include "loader.h"
#include "WebCoreUrlResponseInfo.h"
#include "WebCoreLoaderContainer.h"
#include "KWQFormData.h"
using khtml::Cache;
using khtml::CachedObject;
using khtml::CachedImage;
using khtml::DocLoader;
using khtml::Loader;
using khtml::Request;
using KIO::TransferJob;
bool KWQServeRequest(Loader *loader, Request *request, TransferJob *job)
{
LOG(Loading, "Serving request for base %s, url %s",
request->m_docLoader->part()->baseURL().url().latin1(),
request->object->url().string().latin1());
return KWQServeRequest(loader, request->m_docLoader, job);
}
/*
@interface NSDictionary (WebCore_Extras)
- (id)_webcore_initWithHeaderString:(NSString *)string;
@end
@implementation NSDictionary (WebCore_Extras)
- (id)_webcore_initWithHeaderString:(NSString *)string
{
NSMutableDictionary *headers = [[NSMutableDictionary alloc] init];
NSArray *lines = [string componentsSeparatedByString:@"\r\n"];
NSEnumerator *e = [lines objectEnumerator];
NSString *line;
NSString *lastHeaderName = nil;
while ((line = (NSString *)[e nextObject]) != nil) {
if (([line characterAtIndex:0] == ' ' || [line characterAtIndex:0] == '\t')
&& lastHeaderName != nil) {
// lines that start with space or tab continue the previous header value
NSString *oldVal = [headers objectForKey:lastHeaderName];
ASSERT(oldVal);
[headers setObject:[NSString stringWithFormat:@"%@ %@", oldVal, [line stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" \t"]]]
forKey:lastHeaderName];
continue;
}
NSRange colonRange = [line rangeOfString:@":"];
if (colonRange.location != NSNotFound) {
// don't worry about case, assume lower levels will take care of it
NSString *headerName = [[line substringToIndex:colonRange.location] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" \t"]];
NSString *headerValue = [[line substringFromIndex:colonRange.location + 1] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" \t"]];
NSString *oldVal = [headers objectForKey:headerName];
if (oldVal) {
headerValue = [NSString stringWithFormat:@"%@, %@", oldVal, headerValue];
}
[headers setObject:headerValue forKey:headerName];
lastHeaderName = headerName;
}
}
self = [self initWithDictionary:headers];
[headers release];
return self;
}
@end
*/
bool KWQServeRequest(Loader *loader, DocLoader *docLoader, TransferJob *job)
{
KWQKHTMLPart *part = static_cast<KWQKHTMLPart *>(docLoader->part());
CWebCoreBridge* bridge = part->bridge();
part->didTellBridgeAboutLoad(job->url().url());
KWQResourceLoader *resourceLoader = new KWQResourceLoader(job);
MWebCoreResourceHandle* handle = NULL;
/*
todo: post
NSDictionary *headerDict = nil;
QString headerString = job->queryMetaData("customHTTPHeader");
if (!headerString.isEmpty()) {
headerDict = [[NSDictionary alloc] _webcore_initWithHeaderString:headerString.getNSString()];
}*/
if (job->method() == "POST") {
CArrayFixFlat<TWebCoreKeyValuePair>* headers = new CArrayFixFlat<TWebCoreKeyValuePair>(4);
if (headers) {
const QString acceptKey("accept");
const QString priorityKey("priority");
const QString contentTypeKey("content-type");
const QString boundaryKey("boundary");
QString acceptValue;
QString priorityValue;
QString contentTypeValue;
QString boundaryValue;
// add accept header //not sure this is needed
TWebCoreKeyValuePair acceptheader;
acceptValue = job->queryMetaData(acceptKey);
if (acceptValue.length()) {
acceptheader.iKey.Set(acceptKey.Des());
acceptheader.iValue.Set(acceptValue.Des());
TRAP_IGNORE(headers->AppendL(acceptheader));
}
// not really a header, just pass up the start //not sure this is needed
TWebCoreKeyValuePair priorityheader;
priorityValue = job->queryMetaData(priorityKey);
if (priorityValue.length()) {
priorityheader.iKey.Set(priorityKey.Des());
priorityheader.iValue.Set(priorityValue.Des());
TRAP_IGNORE(headers->AppendL(priorityheader));
}
TWebCoreKeyValuePair contentTypeHeader;
contentTypeValue= job->queryMetaData(contentTypeKey);
if (contentTypeValue.length()) {
contentTypeHeader.iKey.Set(contentTypeKey.Des());
contentTypeHeader.iValue.Set(contentTypeKey.Des());
TRAP_IGNORE(headers->AppendL(contentTypeHeader));
}
TWebCoreKeyValuePair boundaryheader;
boundaryValue = job->queryMetaData(boundaryKey);
if (boundaryValue.length()) {
boundaryheader.iKey.Set(boundaryKey.Des());
boundaryheader.iValue.Set(boundaryValue.Des());
TRAP_IGNORE(headers->AppendL(boundaryheader));
}
QString customHeaderString = job->queryMetaData("customHTTPHeader");
int b = 0, e = 0;
int l = customHeaderString.length();
QString names[8]; // keep temporary strings alive
QString vals[8];
int n = 0;
while(e<l && n<8){
while (e<l && customHeaderString[e]!=':')
e++;
if (e==b)
break;
QString name = customHeaderString.mid(b,e-b);
e++; // :
b=e;
while (e<l && customHeaderString[e]!='\r')
e++;
if (e==b)
break;
QString val = customHeaderString.mid(b,e-b);
e++; // \r
e++; // \n
b=e;
TWebCoreKeyValuePair hval;
names[n] = name.stripWhiteSpace().lower();
vals[n] = val.stripWhiteSpace().lower();
hval.iKey.Set(names[n].Des());
hval.iValue.Set(vals[n].Des());
TRAP_IGNORE(headers->AppendL(hval));
n++;
}
RArray<TWebCoreFormDataItem> formData;
WebCoreFromFormData(job->postData(), formData);
handle = bridge->Client().StartLoadingResource( *resourceLoader, job->url().Des(), headers, formData);
formData.Close();
delete headers;
}
} else {
CArrayFixFlat<TWebCoreKeyValuePair>* headers = new CArrayFixFlat<TWebCoreKeyValuePair>(2);
const QString acceptKey("accept");
const QString priorityKey("priority");
const QString referrerKey("referrer");
QString acceptValue;
QString priorityValue;
QString referrerValue;
if (headers) {
// add accept header
TWebCoreKeyValuePair acceptheader;
acceptValue = job->queryMetaData(acceptKey);
if (acceptValue.length()) {
acceptheader.iKey.Set(acceptKey.Des());
acceptheader.iValue.Set(acceptValue.Des());
TRAP_IGNORE(headers->AppendL(acceptheader));
}
// not really a header, just pass up the priority
TWebCoreKeyValuePair priorityheader;
priorityValue = job->queryMetaData(priorityKey);
if (priorityValue.length()) {
priorityheader.iKey.Set(priorityKey.Des());
priorityheader.iValue.Set(priorityValue.Des());
TRAP_IGNORE(headers->AppendL(priorityheader));
}
TWebCoreKeyValuePair referrerheader;
referrerValue = job->queryMetaData(referrerKey);
if (referrerValue.length()) {
referrerheader.iKey.Set(referrerKey.Des());
referrerheader.iValue.Set(referrerValue.Des());
TRAP_IGNORE(headers->AppendL(referrerheader));
}
}
handle = bridge->Client().StartLoadingResource( *resourceLoader, job->url().Des(), headers );
delete headers;
}
resourceLoader->setHandle( handle );
return handle != NULL;
}
QByteArray KWQServeSynchronousRequest(Loader *loader, DocLoader *docLoader, TransferJob *job, KURL &finalURL, QString &responseHeaders)
{
// todo sync request
ASSERT(false);
return QByteArray();
}
int KWQNumberOfPendingOrLoadingRequests(khtml::DocLoader *dl)
{
return Cache::loader()->numRequests(dl);
}
bool KWQCheckIfReloading(DocLoader *loader)
{
return ((KWQKHTMLPart*)(loader->part()))->bridge()->Client().IsReloading();
}
void KWQUpdateCache( const KURL &url, const QString &expireDate )
{
TPtrC expireDatePtr( expireDate.Des() );
TPtrC urlPtr( url.url().Des() );
TRAP_IGNORE( TWebCoreLoaderContainer::LoaderContainer()->UpdateCacheL( urlPtr, expireDatePtr ) );
}
void KWQCheckCacheObjectStatus(DocLoader *loader, CachedObject *cachedObject)
{
// Return from the function for objects that we didn't load from the cache.
if (!cachedObject)
return;
// Notify the caller that we "loaded".
KWQKHTMLPart *part = static_cast<KWQKHTMLPart *>(loader->part());
CWebCoreBridge *bridge = part->bridge();
QString urlString = cachedObject->url().string();
switch (cachedObject->status()) {
case CachedObject::Persistent:
case CachedObject::Cached:
case CachedObject::Uncacheable:
break;
case CachedObject::NotCached:
case CachedObject::Unknown:
case CachedObject::New:
case CachedObject::Pending:
return;
}
ASSERT(cachedObject->response());
if (!part->haveToldBridgeAboutLoad(urlString)) {
bridge->Client().ObjectLoadedFromCacheWithURL( urlString.Des(), cachedObject->response(),
KNullDesC8 /*cachedObject->allData()*/ );
part->didTellBridgeAboutLoad(urlString);
}
}
bool KWQIsResponseURLEqualToURL(MWebCoreUrlResponseHeaderInfo *response, const DOM::DOMString &m_url)
{
//NSURL *responseURL = [(NSURLResponse *)response URL];
//NSString *urlString = [responseURL absoluteString];
TPtrC urlString = response->ResponseUrl();
if (m_url.length() != urlString.Length())
return false;
return m_url.string()==QString::FromDes(urlString);
}
QString KWQResponseURL(MWebCoreUrlResponseHeaderInfo *response)
{
return QString::FromDes(response->ResponseUrl());
}
QString KWQResponseMIMEType(MWebCoreUrlResponseHeaderInfo *response)
{
return QString::FromDes(response->ContentType());
}
time_t KWQCacheObjectExpiresTime(khtml::DocLoader *docLoader, MWebCoreUrlResponseHeaderInfo *response)
{
KWQKHTMLPart *part = static_cast<KWQKHTMLPart *>(docLoader->part());
CWebCoreBridge *bridge = part->bridge();
TDateTime exires = bridge->Client().ExpiresTimeForResponse( response );
time_t timet;
//
struct tm* timePtr = new struct tm;
// struct tm
// {
// int tm_sec; /* seconds (0-59) */
// int tm_min; /* minutes (0-59) */
// int tm_hour; /* hours since midnight (0-23) */
// int tm_mday; /* day of month (1-31) */
// int tm_mon; /* month (0-11, January = 0) */
// int tm_year; /* years since 1900 */
// int tm_wday; /* day of week (0-6, Sunday = 0) */
// int tm_yday; /* day of year (0-365, Jan 1st = 0) */
// int tm_isdst; /* negative means dst status unknown */
// };
if( timePtr ){
//
timePtr->tm_sec = exires.Second();
timePtr->tm_min = exires.Minute();
timePtr->tm_hour = exires.Hour();
timePtr->tm_mday = exires.Day()+ 1;
timePtr->tm_mon = exires.Month();
timePtr->tm_year = exires.Year() - 1900;
// ??
timePtr->tm_wday = 0;
timePtr->tm_yday = 0;
timePtr->tm_isdst = -1;
timet = mktime( timePtr );
}
else
timet = time( 0 );
//
delete timePtr;
return timet;
}
KWQLoader::KWQLoader(Loader *loader)
: _requestStarted(loader, SIGNAL(requestStarted(khtml::DocLoader *, khtml::CachedObject *)))
, _requestDone(loader, SIGNAL(requestDone(khtml::DocLoader *, khtml::CachedObject *)))
, _requestFailed(loader, SIGNAL(requestFailed(khtml::DocLoader *, khtml::CachedObject *)))
{
}
namespace khtml {
void CachedObject::setResponse(MWebCoreUrlResponseHeaderInfo *response)
{
if (m_response)
m_response->DeRef();
if (response)
response->Ref();
m_response = response;
}
/*void CachedObject::setAllData(const TDesC8& allData)
{
// ref?
m_allData.Set(allData);
}*/
} // namespace
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -