[webkit-changes] cvs commit: WebCore/khtml/ecma xmlhttprequest.cpp
xmlhttprequest.h
Adele
adele at opensource.apple.com
Mon Dec 19 11:17:33 PST 2005
adele 05/12/19 11:17:33
Modified: . ChangeLog
khtml/ecma xmlhttprequest.cpp xmlhttprequest.h
Log:
Reviewed by Darin, committed by Adele.
- fix http://bugzilla.opendarwin.org/show_bug.cgi?id=5744
XMLHttpRequest does not apply page encoding after assigning via innerHtml
* khtml/ecma/xmlhttprequest.cpp:
(getMIMEType): A helper function to get MIME type from a Content-Type string.
(getCharset): A helper function to get charset from a Content-Type string.
(KJS::XMLHttpRequest::getValueProperty): Factored out responseIsXML().
(KJS::XMLHttpRequest::getResponseHeader): Return QString instead of JSValue
(to get rid of unnecessary JSLocks).
(KJS::XMLHttpRequest::responseIsXML): A new method that analyses Content-Type.
(KJS::XMLHttpRequest::slotData): Use a correct charset for responses, see bug for details.
(KJS::XMLHttpRequestProtoFunc::callAsFunction): Update for getResponseHeader() changes
* khtml/ecma/xmlhttprequest.h:
Revision Changes Path
1.2 +17 -0 WebCore/ChangeLog
Index: ChangeLog
===================================================================
RCS file: /cvs/root/WebCore/ChangeLog,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ChangeLog 19 Dec 2005 19:16:44 -0000 1.1
+++ ChangeLog 19 Dec 2005 19:17:32 -0000 1.2
@@ -1,2 +1,19 @@
+2005-12-19 Alexey Proskuryakov <ap at nypop.com>
+
+ Reviewed by Darin, committed by Adele.
+
+ - fix http://bugzilla.opendarwin.org/show_bug.cgi?id=5744
+ XMLHttpRequest does not apply page encoding after assigning via innerHtml
+
+ * khtml/ecma/xmlhttprequest.cpp:
+ (getMIMEType): A helper function to get MIME type from a Content-Type string.
+ (getCharset): A helper function to get charset from a Content-Type string.
+ (KJS::XMLHttpRequest::getValueProperty): Factored out responseIsXML().
+ (KJS::XMLHttpRequest::getResponseHeader): Return QString instead of JSValue
+ (to get rid of unnecessary JSLocks).
+ (KJS::XMLHttpRequest::responseIsXML): A new method that analyses Content-Type.
+ (KJS::XMLHttpRequest::slotData): Use a correct charset for responses, see bug for details.
+ (KJS::XMLHttpRequestProtoFunc::callAsFunction): Update for getResponseHeader() changes
+ * khtml/ecma/xmlhttprequest.h:
== Rolled over to ChangeLog-2005-12-19 ==
1.53 +83 -32 WebCore/khtml/ecma/xmlhttprequest.cpp
Index: xmlhttprequest.cpp
===================================================================
RCS file: /cvs/root/WebCore/khtml/ecma/xmlhttprequest.cpp,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -r1.52 -r1.53
--- xmlhttprequest.cpp 16 Dec 2005 08:08:14 -0000 1.52
+++ xmlhttprequest.cpp 19 Dec 2005 19:17:32 -0000 1.53
@@ -49,6 +49,50 @@
using khtml::Decoder;
+static inline QString getMIMEType(const QString& contentTypeString)
+{
+ return QStringList::split(";", contentTypeString, true)[0].stripWhiteSpace();
+}
+
+static QString getCharset(const QString& contentTypeString)
+{
+ int pos = 0;
+ int length = (int)contentTypeString.length();
+
+ while (pos < length) {
+ pos = contentTypeString.find("charset", pos, false);
+ if (pos <= 0)
+ return QString();
+
+ // is what we found a beginning of a word?
+ if (contentTypeString[pos-1] > ' ' && contentTypeString[pos-1] != ';') {
+ pos += 7;
+ continue;
+ }
+
+ pos += 7;
+
+ // skip whitespace
+ while (pos != length && contentTypeString[pos] <= ' ')
+ ++pos;
+
+ if (contentTypeString[pos++] != '=') // this "charset" substring wasn't a parameter name, but there may be others
+ continue;
+
+ while (pos != length && (contentTypeString[pos] <= ' ' || contentTypeString[pos] == '"' || contentTypeString[pos] == '\''))
+ ++pos;
+
+ // we don't handle spaces within quoted parameter values, because charset names cannot have any
+ int endpos = pos;
+ while (pos != length && contentTypeString[endpos] > ' ' && contentTypeString[endpos] != '"' && contentTypeString[endpos] != '\'' && contentTypeString[endpos] != ';')
+ ++endpos;
+
+ return contentTypeString.mid(pos, endpos-pos);
+ }
+
+ return QString();
+}
+
namespace KJS {
////////////////////// XMLHttpRequest Object ////////////////////////
@@ -137,21 +181,9 @@
if (state != Completed) {
return jsUndefined();
}
+
if (!createdDocument) {
- QString mimeType;
-
- if (MIMETypeOverride.isEmpty()) {
- JSValue *header = getResponseHeader("Content-Type");
- if (header->isUndefined()) {
- mimeType = "text/xml";
- } else {
- mimeType = QStringList::split(";", header->toString(exec).qstring(), true)[0].stripWhiteSpace();
- }
- } else {
- mimeType = MIMETypeOverride;
- }
-
- if (typeIsXML = DOMImplementationImpl::isXMLMIMEType(mimeType)) {
+ if (typeIsXML = responseIsXML()) {
responseXML = doc->implementation()->createDocument();
DocumentImpl *docImpl = responseXML.get();
@@ -422,11 +454,10 @@
return jsString(responseHeaders.mid(endOfLine + 1) + "\n");
}
-JSValue *XMLHttpRequest::getResponseHeader(const QString& name) const
+QString XMLHttpRequest::getResponseHeader(const QString& name) const
{
- if (responseHeaders.isEmpty()) {
- return jsUndefined();
- }
+ if (responseHeaders.isEmpty())
+ return QString();
QRegExp headerLinePattern(name + ":", false);
@@ -440,14 +471,23 @@
headerLinePos = headerLinePattern.match(responseHeaders, headerLinePos + 1, &matchLength);
}
-
- if (headerLinePos == -1) {
- return jsUndefined();
- }
+ if (headerLinePos == -1)
+ return QString();
int endOfLine = responseHeaders.find("\n", headerLinePos + matchLength);
+
+ return responseHeaders.mid(headerLinePos + matchLength, endOfLine - (headerLinePos + matchLength)).stripWhiteSpace();
+}
- return jsString(responseHeaders.mid(headerLinePos + matchLength, endOfLine - (headerLinePos + matchLength)).stripWhiteSpace());
+bool XMLHttpRequest::responseIsXML() const
+{
+ QString mimeType = getMIMEType(MIMETypeOverride);
+ if (mimeType.isEmpty())
+ mimeType = getMIMEType(getResponseHeader("Content-Type"));
+ if (mimeType.isEmpty())
+ mimeType = "text/xml";
+
+ return DOMImplementationImpl::isXMLMIMEType(mimeType);
}
JSValue *XMLHttpRequest::getStatus() const
@@ -548,21 +588,27 @@
}
}
-void XMLHttpRequest::slotData( KIO::Job*, const char *data, int len )
+void XMLHttpRequest::slotData(KIO::Job*, const char *data, int len)
{
- if (state < Loaded) {
+ if (responseHeaders.isEmpty() && job)
responseHeaders = job->queryMetaData("HTTP-Headers");
- encoding = job->queryMetaData("charset");
+
+ if (state < Loaded)
changeState(Loaded);
- }
-
- if ( decoder == NULL ) {
+ if (decoder == NULL) {
+ encoding = getCharset(MIMETypeOverride);
+ if (encoding.isEmpty())
+ encoding = getCharset(getResponseHeader("Content-Type"));
+ if (encoding.isEmpty() && job)
+ encoding = job->queryMetaData("charset");
+
decoder = new Decoder;
- if (!encoding.isNull())
+ if (!encoding.isEmpty())
decoder->setEncoding(encoding.latin1(), Decoder::EncodingFromHTTPHeader);
else {
- // FIXME: Inherit the default encoding from the parent document?
+ // only allow Decoder to look inside the response if it's XML
+ decoder->setEncoding("UTF-8", responseIsXML() ? Decoder::DefaultEncoding : Decoder::EncodingFromHTTPHeader);
}
}
if (len == 0)
@@ -647,8 +693,13 @@
if (args.size() != 1) {
return jsUndefined();
}
+
+ QString header = request->getResponseHeader(args[0]->toString(exec).qstring());
+
+ if (header.isNull())
+ return jsUndefined();
- return request->getResponseHeader(args[0]->toString(exec).qstring());
+ return jsString(header);
}
case XMLHttpRequest::Open:
{
1.24 +8 -7 WebCore/khtml/ecma/xmlhttprequest.h
Index: xmlhttprequest.h
===================================================================
RCS file: /cvs/root/WebCore/khtml/ecma/xmlhttprequest.h,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- xmlhttprequest.h 11 Dec 2005 02:06:08 -0000 1.23
+++ xmlhttprequest.h 19 Dec 2005 19:17:32 -0000 1.24
@@ -44,11 +44,11 @@
// these exact numeric values are important because JS expects them
enum XMLHttpRequestState {
- Uninitialized = 0,
- Loading = 1,
- Loaded = 2,
- Interactive = 3,
- Completed = 4
+ Uninitialized = 0, // open() has not been called yet
+ Loading = 1, // send() has not been called yet
+ Loaded = 2, // send() has been called, headers and status are available
+ Interactive = 3, // Downloading, responseText holds the partial data
+ Completed = 4 // Finished with all operations
};
class XMLHttpRequestConstructorImp : public JSObject {
@@ -101,8 +101,9 @@
void abort();
void setRequestHeader(const QString& name, const QString &value);
JSValue *getAllResponseHeaders() const;
- JSValue *getResponseHeader(const QString& name) const;
-
+ QString getResponseHeader(const QString& name) const;
+ bool responseIsXML() const;
+
void changeState(XMLHttpRequestState newState);
static QPtrDict< QPtrDict<XMLHttpRequest> > &requestsByDocument();
More information about the webkit-changes
mailing list