📄 xmlhttprequest.cpp
字号:
data = KWQServeSynchronousRequest(khtml::Cache::loader(), doc->docLoader(), job, finalURL, headers);#else QMap<QString, QString> metaData; if ( NetAccess::synchronousRun( job, 0, &data, &finalURL, &metaData ) ) { headers = metaData[ "HTTP-Headers" ]; }#endif job = 0; processSyncLoadResults(data, finalURL, headers); return; } qObject->connect( job, SIGNAL( result( KIO::Job* ) ), SLOT( slotFinished( KIO::Job* ) ) );#ifdef APPLE_CHANGES qObject->connect( job, SIGNAL( data( KIO::Job*, const char*, int ) ), SLOT( slotData( KIO::Job*, const char*, int ) ) );#else qObject->connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ), SLOT( slotData( KIO::Job*, const QByteArray& ) ) );#endif qObject->connect( job, SIGNAL(redirection(KIO::Job*, const KURL& ) ), SLOT( slotRedirection(KIO::Job*, const KURL&) ) );#ifdef APPLE_CHANGES KWQServeRequest(khtml::Cache::loader(), doc->docLoader(), job);#else KIO::Scheduler::scheduleJob( job );#endif}void XMLHttpRequest::abort(){ if (job) { job->kill(); job = 0; } delete decoder; decoder = 0; aborted = true;}void XMLHttpRequest::setRequestHeader(const QString& _name, const QString &value){ QString name = _name.lower().stripWhiteSpace(); // Content-type needs to be set seperately from the other headers if(name == "content-type") { contentType = "Content-type: " + value; return; } // Sanitize the referrer header to protect against spoofing... if(name == "referer") { KURL referrerURL(value); if (urlMatchesDocumentDomain(referrerURL)) requestHeaders[name] = referrerURL.url(); return; } // Sanitize the request headers below and handle them as if they are // calls to open. Otherwise, we will end up ignoring them all together! // TODO: Do something about "put" which kio_http sort of supports and // the webDAV headers such as PROPFIND etc... if (name == "get" || name == "post") { KURL reqURL (doc->URL(), value.stripWhiteSpace()); open(name, reqURL, async); return; } // Reject all banned headers. See BANNED_HTTP_HEADERS above. // kdDebug() << "Banned HTTP Headers: " << BANNED_HTTP_HEADERS << endl; QStringList bannedHeaders = QStringList::split(',', QString::fromLatin1(BANNED_HTTP_HEADERS)); if (bannedHeaders.contains(name)) return; // Denied requestHeaders[name] = value.stripWhiteSpace();}Value XMLHttpRequest::getAllResponseHeaders() const{ if (responseHeaders.isEmpty()) { return Undefined(); } int endOfLine = responseHeaders.find("\n"); if (endOfLine == -1) { return Undefined(); } return String(responseHeaders.mid(endOfLine + 1) + "\n");}Value XMLHttpRequest::getResponseHeader(const QString& name) const{ if (responseHeaders.isEmpty()) { return Undefined(); } QRegExp headerLinePattern(name + ":", false); int matchLength; int headerLinePos = headerLinePattern.search(responseHeaders, 0); matchLength = headerLinePattern.matchedLength(); while (headerLinePos != -1) { if (headerLinePos == 0 || responseHeaders[headerLinePos-1] == '\n') { break; } headerLinePos = headerLinePattern.search(responseHeaders, headerLinePos + 1); matchLength = headerLinePattern.matchedLength(); } if (headerLinePos == -1) { return Undefined(); } int endOfLine = responseHeaders.find("\n", headerLinePos + matchLength); return String(responseHeaders.mid(headerLinePos + matchLength, endOfLine - (headerLinePos + matchLength)).stripWhiteSpace());}static Value httpStatus(const QString& response, bool textStatus = false){ if (response.isEmpty()) { return Undefined(); } int endOfLine = response.find("\n"); QString firstLine = (endOfLine == -1) ? response : response.left(endOfLine); int codeStart = firstLine.find(" "); int codeEnd = firstLine.find(" ", codeStart + 1); if (codeStart == -1 || codeEnd == -1) { return Undefined(); } if (textStatus) { QString statusText = firstLine.mid(codeEnd + 1, endOfLine - (codeEnd + 1)).stripWhiteSpace(); return String(statusText); } QString number = firstLine.mid(codeStart + 1, codeEnd - (codeStart + 1)); bool ok = false; int code = number.toInt(&ok); if (!ok) { return Undefined(); } return Number(code);}Value XMLHttpRequest::getStatus() const{ return httpStatus(responseHeaders);}Value XMLHttpRequest::getStatusText() const{ return httpStatus(responseHeaders, true);}void XMLHttpRequest::processSyncLoadResults(const QByteArray &data, const KURL &finalURL, const QString &headers){ if (!urlMatchesDocumentDomain(finalURL)) { abort(); return; } responseHeaders = headers; changeState(Loaded); if (aborted) { return; }#ifdef APPLE_CHANGES const char *bytes = (const char *)data.data(); int len = (int)data.size(); slotData(0, bytes, len);#else slotData(0, data);#endif if (aborted) { return; } slotFinished(0);}void XMLHttpRequest::slotFinished(KIO::Job *){ if (decoder) { response += decoder->flush(); } // make sure to forget about the job before emitting completed, // since changeState triggers JS code, which might e.g. call abort. job = 0; changeState(Completed); delete decoder; decoder = 0;}void XMLHttpRequest::slotRedirection(KIO::Job*, const KURL& url){ if (!urlMatchesDocumentDomain(url)) { abort(); }}#ifdef APPLE_CHANGESvoid XMLHttpRequest::slotData( KIO::Job*, const char *data, int len )#elsevoid XMLHttpRequest::slotData(KIO::Job*, const QByteArray &_data)#endif{ if (state < Loaded ) { responseHeaders = job->queryMetaData("HTTP-Headers"); // NOTE: Replace a 304 response with a 200! Both IE and Mozilla do this. // Problem first reported through bug# 110272. int codeStart = responseHeaders.find("304"); if ( codeStart != -1) { int codeEnd = responseHeaders.find("\n", codeStart+3); if (codeEnd != -1) responseHeaders.replace(codeStart, (codeEnd-codeStart), "200 OK"); } changeState(Loaded); }#ifndef APPLE_CHANGES const char *data = (const char *)_data.data(); int len = (int)_data.size();#endif if ( decoder == NULL ) { int pos = responseHeaders.find("content-type:", 0, false); if ( pos > -1 ) { pos += 13; int index = responseHeaders.find('\n', pos); QString type = responseHeaders.mid(pos, (index-pos)); index = type.find (';'); if (index > -1) encoding = type.mid( index+1 ).remove(QRegExp("charset[ ]*=[ ]*", false)).stripWhiteSpace(); } decoder = new Decoder; if (!encoding.isNull()) decoder->setEncoding(encoding.latin1(), Decoder::EncodingFromHTTPHeader); else { // FIXME: Inherit the default encoding from the parent document? } } if (len == 0) return; if (len == -1) len = strlen(data); QString decoded = decoder->decode(data, len); response += decoded; if (!aborted) { changeState(Interactive); }}Value XMLHttpRequestProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args){ if (!thisObj.inherits(&XMLHttpRequest::info)) { Object err = Error::create(exec,TypeError); exec->setException(err); return err; } XMLHttpRequest *request = static_cast<XMLHttpRequest *>(thisObj.imp()); switch (id) { case XMLHttpRequest::Abort: request->abort(); return Undefined(); case XMLHttpRequest::GetAllResponseHeaders: if (args.size() != 0) { return Undefined(); } return request->getAllResponseHeaders(); case XMLHttpRequest::GetResponseHeader: if (args.size() != 1) { return Undefined(); } return request->getResponseHeader(args[0].toString(exec).qstring()); case XMLHttpRequest::Open: { if (args.size() < 2 || args.size() > 5) { return Undefined(); } QString method = args[0].toString(exec).qstring(); KHTMLPart *part = ::qt_cast<KHTMLPart *>(Window::retrieveActive(exec)->part()); if (!part) return Undefined(); KURL url = KURL(part->document().completeURL(args[1].toString(exec).qstring()).string()); bool async = true; if (args.size() >= 3) { async = args[2].toBoolean(exec); } if (args.size() >= 4) { url.setUser(args[3].toString(exec).qstring()); } if (args.size() >= 5) { url.setPass(args[4].toString(exec).qstring()); } request->open(method, url, async); return Undefined(); } case XMLHttpRequest::Send: { if (args.size() != 1) { return Undefined(); } if (request->state != Loading) { return Undefined(); } QString body; Object obj = Object::dynamicCast(args[0]); if (obj.isValid() && obj.inherits(&DOMDocument::info)) { DOM::Node docNode = static_cast<KJS::DOMDocument *>(obj.imp())->toNode(); DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl *>(docNode.handle()); try { body = doc->toString().string(); // FIXME: also need to set content type, including encoding! } catch(DOM::DOMException& e) { Object err = Error::create(exec, GeneralError, "Exception serializing document"); exec->setException(err); } } else { body = args[0].toString(exec).qstring(); } request->send(body); return Undefined(); } case XMLHttpRequest::SetRequestHeader: if (args.size() != 2) { return Undefined(); } request->setRequestHeader(args[0].toString(exec).qstring(), args[1].toString(exec).qstring()); return Undefined(); } return Undefined();}} // end namespace#include "xmlhttprequest.moc"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -