WebCore:
authormjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 Nov 2003 23:27:33 +0000 (23:27 +0000)
committermjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 Nov 2003 23:27:33 +0000 (23:27 +0000)
        Reviewed by Ken.

WebCore part of fix for:

<rdar://problem/3487134>: Implement http request/response status and headers for XMLHttpRequest

        * khtml/ecma/xmlhttprequest.cpp:
        (KJS::XMLHttpRequest::getValueProperty): Call appropriate methods for
status and statusText.
        (KJS::XMLHttpRequest::send): Set request headers as "customHeaders"
metadata property.
        (KJS::XMLHttpRequest::setRequestHeader): Simply append to header
string.
        (KJS::XMLHttpRequest::getAllResponseHeaders): Return the header string
except for the first line.
(KJS::XMLHttpRequest::getResponseHeader): Scan the response header
string for the header field. Not sure if it's worth being more
efficient.
        (KJS::XMLHttpRequest::getStatus): Try to pull a code out
of the status line.
        (KJS::XMLHttpRequest::getStatusText): Pull the first line
off the headers (if any), otherwise return undefined.
        (KJS::XMLHttpRequest::slotData): The first time through, save
the response headers, retrieved from "HTTP-Headers" metadata
property.
        (KJS::XMLHttpRequestProtoFunc::tryCall): Make setRequestHeader,
getResponseHeader, getAllResponseHeaders call the right thing.
        * khtml/ecma/xmlhttprequest.h:
        * kwq/KWQKJobClasses.h:
        * kwq/KWQKJobClasses.mm:
        (KIO::TransferJobPrivate::TransferJobPrivate): Added header
support.
        (KIO::TransferJobPrivate::~TransferJobPrivate):
        (KIO::TransferJob::assembleResponseHeaders): Get a header string
out of the response if needed.
        (KIO::TransferJob::queryMetaData): Special-case "HTTP-Headers".
        (KIO::TransferJob::emitReceivedResponse): Save response.
        * kwq/KWQLoader.h:
        * kwq/KWQLoader.mm:
        (-[NSDictionary _webcore_initWithHeaderString:]): Helper method to
turn a string of header fields into a dictionary.
        (KWQServeRequest): Pass custom headers through.
        (KWQResponseMIMEType): Admit it's an NSURLResponse *.
        (KWQResponseHeaderString): Assembled status code and response
header fields into response header. Cheat a little on the status
line.
        * kwq/KWQResourceLoader.mm:
        (-[KWQResourceLoader receivedResponse:]): Admit it's an
NSURLResponse *.
        * kwq/WebCoreResourceLoader.h: Ditto.
* kwq/WebCoreBridge.h: Add customHeader: arguments.

WebKit:

        Reviewed by Ken.

WebKit part of fix for:

<rdar://problem/3487134>: Implement http request/response status and headers for XMLHttpRequest

        * WebCoreSupport.subproj/WebBridge.m:
        (-[WebBridge startLoadingResource:withURL:customHeaders:]): Added customHeaders
parameter.
        (-[WebBridge startLoadingResource:withURL:customHeaders:postData:]): Ditto.
        * WebCoreSupport.subproj/WebSubresourceClient.h:
        * WebCoreSupport.subproj/WebSubresourceClient.m:
        (+[WebSubresourceClient startLoadingResource:withRequest:customHeaders:referrer:forDataSource:]): Add the custom headers.
        (+[WebSubresourceClient startLoadingResource:withURL:customHeaders:referrer:forDataSource:]): Pass along the custom headers.
        (+[WebSubresourceClient startLoadingResource:withURL:customHeaders:postData:referrer:forDataSource:]): Pass along the custom headers.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@5625 268f45cc-cd09-0410-ab3c-d52691b4dbfc

16 files changed:
WebCore/ChangeLog-2005-08-23
WebCore/khtml/ecma/xmlhttprequest.cpp
WebCore/khtml/ecma/xmlhttprequest.h
WebCore/kwq/KWQKJobClasses.h
WebCore/kwq/KWQKJobClasses.mm
WebCore/kwq/KWQLoader.h
WebCore/kwq/KWQLoader.mm
WebCore/kwq/KWQResourceLoader.mm
WebCore/kwq/WebCoreBridge.h
WebCore/kwq/WebCoreResourceLoader.h
WebKit/ChangeLog
WebKit/WebCoreSupport.subproj/WebBridge.m
WebKit/WebCoreSupport.subproj/WebSubresourceClient.h
WebKit/WebCoreSupport.subproj/WebSubresourceClient.m
WebKit/WebCoreSupport.subproj/WebSubresourceLoader.h
WebKit/WebCoreSupport.subproj/WebSubresourceLoader.m

index a7a7eff..864fe6a 100644 (file)
@@ -1,3 +1,57 @@
+2003-11-21  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Ken.
+
+       WebCore part of fix for:
+       
+       <rdar://problem/3487134>: Implement http request/response status and headers for XMLHttpRequest
+
+        * khtml/ecma/xmlhttprequest.cpp:
+        (KJS::XMLHttpRequest::getValueProperty): Call appropriate methods for
+       status and statusText.
+        (KJS::XMLHttpRequest::send): Set request headers as "customHeaders"
+       metadata property.
+        (KJS::XMLHttpRequest::setRequestHeader): Simply append to header
+       string.
+        (KJS::XMLHttpRequest::getAllResponseHeaders): Return the header string
+       except for the first line.
+       (KJS::XMLHttpRequest::getResponseHeader): Scan the response header
+       string for the header field. Not sure if it's worth being more
+       efficient.
+        (KJS::XMLHttpRequest::getStatus): Try to pull a code out
+       of the status line.
+        (KJS::XMLHttpRequest::getStatusText): Pull the first line
+       off the headers (if any), otherwise return undefined.
+        (KJS::XMLHttpRequest::slotData): The first time through, save
+       the response headers, retrieved from "HTTP-Headers" metadata
+       property.
+        (KJS::XMLHttpRequestProtoFunc::tryCall): Make setRequestHeader,
+       getResponseHeader, getAllResponseHeaders call the right thing.
+        * khtml/ecma/xmlhttprequest.h:
+        * kwq/KWQKJobClasses.h:
+        * kwq/KWQKJobClasses.mm:
+        (KIO::TransferJobPrivate::TransferJobPrivate): Added header
+       support.
+        (KIO::TransferJobPrivate::~TransferJobPrivate):
+        (KIO::TransferJob::assembleResponseHeaders): Get a header string
+       out of the response if needed.
+        (KIO::TransferJob::queryMetaData): Special-case "HTTP-Headers".
+        (KIO::TransferJob::emitReceivedResponse): Save response.
+        * kwq/KWQLoader.h:
+        * kwq/KWQLoader.mm:
+        (-[NSDictionary _webcore_initWithHeaderString:]): Helper method to
+       turn a string of header fields into a dictionary.
+        (KWQServeRequest): Pass custom headers through.
+        (KWQResponseMIMEType): Admit it's an NSURLResponse *.
+        (KWQResponseHeaderString): Assembled status code and response
+       header fields into response header. Cheat a little on the status
+       line.
+        * kwq/KWQResourceLoader.mm:
+        (-[KWQResourceLoader receivedResponse:]): Admit it's an
+       NSURLResponse *.
+        * kwq/WebCoreResourceLoader.h: Ditto.
+       * kwq/WebCoreBridge.h: Add customHeader: arguments.
+
 2003-11-21  Chris Blumenberg  <cblu@apple.com>
 
        Fixed: <rdar://problem/3491907>: When viewing applet, view hierarchy was an empty KWQView
index 13d724b..89d1f57 100644 (file)
@@ -130,15 +130,15 @@ Value XMLHttpRequest::getValueProperty(ExecState *, int token) const
   case ResponseXML:
     return Undefined();
   case Status:
-    return Undefined();
+    return getStatus();
   case StatusText:
-    return Undefined();
+    return getStatusText();
   case Onreadystatechange:
-    if (onReadyStateChangeListener && onReadyStateChangeListener->listenerObjImp()) {
-      return onReadyStateChangeListener->listenerObj();
-    } else {
-      return Null();
-    }
+   if (onReadyStateChangeListener && onReadyStateChangeListener->listenerObjImp()) {
+     return onReadyStateChangeListener->listenerObj();
+   } else {
+     return Null();
+   }
   default:
     kdWarning() << "XMLHttpRequest::getValueProperty unhandled token " << token << endl;
     return Value();
@@ -213,6 +213,9 @@ void XMLHttpRequest::send(const QString& _body)
   {
      job = KIO::get( url, false, false );
   }
+  if (requestHeaders.length() > 0) {
+    job->addMetaData("customHTTPHeader", requestHeaders);
+  }
 
   qObject->connect( job, SIGNAL( result( KIO::Job* ) ),
                    SLOT( slotFinished( KIO::Job* ) ) );
@@ -241,6 +244,97 @@ void XMLHttpRequest::abort()
   }
 }
 
+void XMLHttpRequest::setRequestHeader(const QString& name, const QString &value)
+{
+  if (requestHeaders.length() > 0) {
+    requestHeaders += "\r\n";
+  }
+  requestHeaders += name;
+  requestHeaders += ": ";
+  requestHeaders += value;
+}
+
+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.match(responseHeaders, 0, &matchLength);
+  while (headerLinePos != -1) {
+    if (headerLinePos == 0 || responseHeaders[headerLinePos-1] == '\n') {
+      break;
+    }
+    
+    headerLinePos = headerLinePattern.match(responseHeaders, headerLinePos + 1, &matchLength);
+  }
+
+
+  if (headerLinePos == -1) {
+    return Undefined();
+  }
+    
+  int endOfLine = responseHeaders.find("\n", headerLinePos + matchLength);
+
+  return String(responseHeaders.mid(headerLinePos + matchLength, endOfLine - (headerLinePos + matchLength)).stripWhiteSpace());
+}
+
+Value XMLHttpRequest::getStatus() const
+{
+  if (responseHeaders.isEmpty()) {
+    return Undefined();
+  }
+  
+  int endOfLine = responseHeaders.find("\n");
+  QString firstLine = endOfLine == -1 ? responseHeaders : responseHeaders.left(endOfLine);
+  int codeStart = firstLine.find(" ");
+  int codeEnd = firstLine.find(" ", codeStart + 1);
+  
+  if (codeStart == -1 || codeEnd == -1) {
+    return Undefined();
+  }
+  
+  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::getStatusText() const
+{
+  if (responseHeaders.isEmpty()) {
+    return Undefined();
+  }
+  
+  int endOfLine = responseHeaders.find("\n");
+  QString firstLine = endOfLine == -1 ? responseHeaders : responseHeaders.left(endOfLine);
+  
+  return String(firstLine);
+}
+   
 void XMLHttpRequest::slotFinished(KIO::Job *)
 {
   if (decoder) {
@@ -261,13 +355,13 @@ void XMLHttpRequest::slotRedirection(KIO::Job*, const KURL& url)
 }
 
 #if APPLE_CHANGES
-void XMLHttpRequest::slotData( KIO::Job* _job, const char *data, int len )
+void XMLHttpRequest::slotData( KIO::Job*, const char *data, int len )
 #else
-void XMLHttpRequest::slotData(KIO::Job* _job, const QByteArray &_data)
+void XMLHttpRequest::slotData(KIO::Job*, const QByteArray &_data)
 #endif
 {
   if (state < Loaded) {
-    // handle http headers here
+    responseHeaders = job->queryMetaData("HTTP-Headers");
     changeState(Loaded);
   }
   
@@ -314,9 +408,17 @@ Value XMLHttpRequestProtoFunc::tryCall(ExecState *exec, Object &thisObj, const L
     request->abort();
     return Undefined();
   case XMLHttpRequest::GetAllResponseHeaders:
-    return Undefined();
+    if (args.size() != 0) {
+      return Undefined();
+    }
+
+    return request->getAllResponseHeaders();
   case XMLHttpRequest::GetResponseHeader:
-    return Undefined();
+    if (args.size() != 1) {
+      return Undefined();
+    }
+
+    return request->getResponseHeader(args[0].toString(exec).qstring());
   case XMLHttpRequest::Open: 
     {
       if (args.size() < 2 || args.size() > 5) {
@@ -371,6 +473,12 @@ Value XMLHttpRequestProtoFunc::tryCall(ExecState *exec, Object &thisObj, const L
       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();
   }
 
index 94c238a..20798e9 100644 (file)
@@ -66,6 +66,9 @@ namespace KJS {
     friend class XMLHttpRequestProtoFunc;
     friend class XMLHttpRequestQObject;
 
+    Value getStatusText() const;
+    Value getStatus() const;
+
     XMLHttpRequestQObject *qObject;
 
 #if APPLE_CHANGES
@@ -79,6 +82,9 @@ namespace KJS {
     void open(const QString& _method, const KURL& _url, bool _async);
     void send(const QString& _body);
     void abort();
+    void setRequestHeader(const QString& name, const QString &value);
+    Value getAllResponseHeaders() const;
+    Value getResponseHeader(const QString& name) const;
 
     void changeState(XMLHttpRequestState newState);
 
@@ -87,6 +93,7 @@ namespace KJS {
     KURL url;
     QString method;
     bool async;
+    QString requestHeaders;
 
     KIO::TransferJob * job;
 
@@ -96,6 +103,8 @@ namespace KJS {
     khtml::Decoder *decoder;
     QString encoding;
     QString response;
+
+    QString responseHeaders;
   };
 
 
index 11f0f12..f8b1dee 100644 (file)
@@ -76,6 +76,8 @@ public:
     QByteArray postData() const;
     QString method() const;
 private:
+    void assembleResponseHeaders() const;
+
     TransferJobPrivate *d;
 
     KWQSignal m_data;
index e31deda..46f9fe2 100644 (file)
@@ -27,6 +27,7 @@
 
 #import "KWQExceptions.h"
 #import "KWQKJobClasses.h"
+#import "KWQLoader.h"
 #import "KWQResourceLoader.h"
 #import "KWQString.h"
 
@@ -46,6 +47,8 @@ public:
        , URL(kurl)
        , loader(nil)
        , method("GET")
+       , response(0)
+       , assembledResponseHeaders(true)
     {
     }
 
@@ -56,11 +59,14 @@ public:
        , loader(nil)
        , method("POST")
        , postData(_postData)
+       , response(0)
+       , assembledResponseHeaders(true)
     {
     }
 
     ~TransferJobPrivate()
     {
+       KWQReleaseResponse(response);
         [metaData release];
         [loader release];
     }
@@ -71,6 +77,10 @@ public:
     KWQResourceLoader *loader;
     QString method;
     QByteArray postData;
+
+    void *response;
+    bool assembledResponseHeaders;
+    QString responseHeaders;
 };
 
 TransferJob::TransferJob(const KURL &url, bool reload, bool showProgressInfo)
@@ -121,8 +131,22 @@ QString TransferJob::errorText() const
     return QString::null;
 }
 
+void TransferJob::assembleResponseHeaders() const
+{
+    if (!d->assembledResponseHeaders) {
+       d->responseHeaders = QString::fromNSString((NSString *)KWQResponseHeaderString(d->response));
+       d->assembledResponseHeaders = true;
+    }
+
+}
+
 QString TransferJob::queryMetaData(const QString &key) const
 {
+    if (key == "HTTP-Headers") {
+       assembleResponseHeaders();
+       return d->responseHeaders;
+    }
+
     NSString *value = [d->metaData objectForKey:key.getNSString()]; 
     return value ? QString::fromNSString(value) : QString::null;
 }
@@ -186,6 +210,10 @@ void TransferJob::emitResult()
 
 void TransferJob::emitReceivedResponse(void *response)
 {
+    d->assembledResponseHeaders = false;
+    d->response = response;
+    KWQRetainResponse(d->response);
+
     m_receivedResponse.call(this, response);
 }
 
index b424fd9..b0aabf8 100644 (file)
@@ -43,6 +43,7 @@ bool KWQCheckIfReloading(khtml::DocLoader *loader);
 void KWQRetainResponse(void *response);
 void KWQReleaseResponse(void *response);
 void *KWQResponseMIMEType(void *response);
+void *KWQResponseHeaderString(void *response);
 int KWQNumberOfPendingOrLoadingRequests(khtml::DocLoader *dl);
 
 class KWQLoader
index ec09840..49361bd 100644 (file)
@@ -33,6 +33,8 @@
 #import "khtml_part.h"
 #import "loader.h"
 
+#import <Foundation/NSURLResponse.h>
+
 using khtml::Cache;
 using khtml::CachedObject;
 using khtml::CachedImage;
@@ -50,6 +52,58 @@ bool KWQServeRequest(Loader *loader, Request *request, TransferJob *job)
     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());
@@ -62,11 +116,18 @@ bool KWQServeRequest(Loader *loader, DocLoader *docLoader, TransferJob *job)
 
     id <WebCoreResourceHandle> handle;
 
+    NSDictionary *headerDict = nil;
+    QString headerString = job->queryMetaData("customHTTPHeader");
+
+    if (!headerString.isEmpty()) {
+       headerDict = [[NSDictionary alloc] _webcore_initWithHeaderString:headerString.getNSString()];
+    }
+
     if (job->method() == "POST") {
        NSData *postData = [NSData dataWithBytesNoCopy:job->postData().data() length:job->postData().size() freeWhenDone:NO];
-       handle = [bridge startLoadingResource:resourceLoader withURL:job->url().getNSURL() postData:postData];
+       handle = [bridge startLoadingResource:resourceLoader withURL:job->url().getNSURL() customHeaders:headerDict postData:postData];
     } else {
-       handle = [bridge startLoadingResource:resourceLoader withURL:job->url().getNSURL()];
+       handle = [bridge startLoadingResource:resourceLoader withURL:job->url().getNSURL() customHeaders:headerDict];
     }
     [resourceLoader setHandle:handle];
     [resourceLoader release];
@@ -142,19 +203,48 @@ void KWQReleaseResponse(void *response)
     KWQ_UNBLOCK_EXCEPTIONS;
 }
 
-@interface NSObject (WebPrivateResponse)
-- (NSString *)MIMEType;
-@end
-
 void *KWQResponseMIMEType(void *response)
 {
     KWQ_BLOCK_EXCEPTIONS;
-    return [(id)response MIMEType];
+    return [(NSURLResponse *)response MIMEType];
     KWQ_UNBLOCK_EXCEPTIONS;
 
     return NULL;
 }
 
+void *KWQResponseHeaderString(void *response)
+{
+    KWQ_BLOCK_EXCEPTIONS;
+    NSURLResponse *nsResponse = (NSURLResponse *)response;
+    if ([nsResponse isKindOfClass:[NSHTTPURLResponse class]]) {
+       NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)nsResponse;
+       NSMutableString *headerString = [[NSMutableString alloc] init];
+       [headerString appendString:[NSString stringWithFormat:@"HTTP/1.0 %d OK\n", [httpResponse statusCode]]];
+       NSDictionary *headers = [httpResponse allHeaderFields];
+
+       NSEnumerator *e = [headers keyEnumerator];
+       NSString *key;
+       
+       bool first = true;
+       
+       while ((key = [e nextObject]) != nil) {
+           if (first) {
+               first = false;
+           } else {
+               [headerString appendString:@"\n"];
+           }
+           [headerString appendString:key];
+           [headerString appendString:@": "];
+           [headerString appendString:[headers objectForKey:key]];
+       }
+       
+       return headerString;
+    }
+
+    KWQ_UNBLOCK_EXCEPTIONS;
+
+    return NULL;
+}
 
 KWQLoader::KWQLoader(Loader *loader)
     : _requestStarted(loader, SIGNAL(requestStarted(khtml::DocLoader *, khtml::CachedObject *)))
index ec9b077..16cff16 100644 (file)
@@ -51,7 +51,7 @@ using KIO::TransferJob;
     _handle = [handle retain];
 }
 
-- (void)receivedResponse:(id)response
+- (void)receivedResponse:(NSURLResponse *)response
 {
     ASSERT(response);
     ASSERT(_job);
index 40ad7f4..972a70b 100644 (file)
@@ -291,8 +291,8 @@ typedef enum {
 - (BOOL)runJavaScriptConfirmPanelWithMessage:(NSString *)message;
 - (BOOL)runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText returningText:(NSString **)result;
 
-- (id <WebCoreResourceHandle>)startLoadingResource:(id <WebCoreResourceLoader>)loader withURL:(NSURL *)URL;
-- (id <WebCoreResourceHandle>)startLoadingResource:(id <WebCoreResourceLoader>)loader withURL:(NSURL *)URL postData:(NSData *)data;
+- (id <WebCoreResourceHandle>)startLoadingResource:(id <WebCoreResourceLoader>)loader withURL:(NSURL *)URL customHeaders:(NSDictionary *)customHeaders;
+- (id <WebCoreResourceHandle>)startLoadingResource:(id <WebCoreResourceLoader>)loader withURL:(NSURL *)URL customHeaders:(NSDictionary *)customHeaders postData:(NSData *)data;
 - (void)objectLoadedFromCacheWithURL:(NSURL *)URL response:(id)response size:(unsigned)bytes;
 - (BOOL)isReloading;
 
index 80f9390..e1dac63 100644 (file)
@@ -27,7 +27,7 @@
 
 @protocol WebCoreResourceLoader <NSObject>
 
-- (void)receivedResponse:(id)response;
+- (void)receivedResponse:(NSURLResponse *)response;
 
 - (void)addData:(NSData *)data;
 
index 22e5e00..0f435f7 100644 (file)
@@ -1,3 +1,21 @@
+2003-11-21  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Ken.
+
+       WebKit part of fix for:
+       
+       <rdar://problem/3487134>: Implement http request/response status and headers for XMLHttpRequest
+       
+        * WebCoreSupport.subproj/WebBridge.m:
+        (-[WebBridge startLoadingResource:withURL:customHeaders:]): Added customHeaders
+       parameter.
+        (-[WebBridge startLoadingResource:withURL:customHeaders:postData:]): Ditto.
+        * WebCoreSupport.subproj/WebSubresourceClient.h:
+        * WebCoreSupport.subproj/WebSubresourceClient.m:
+        (+[WebSubresourceClient startLoadingResource:withRequest:customHeaders:referrer:forDataSource:]): Add the custom headers.
+        (+[WebSubresourceClient startLoadingResource:withURL:customHeaders:referrer:forDataSource:]): Pass along the custom headers.
+        (+[WebSubresourceClient startLoadingResource:withURL:customHeaders:postData:referrer:forDataSource:]): Pass along the custom headers.
+
 2003-11-21  John Sullivan  <sullivan@apple.com>
 
         - WebKit part of fix for <rdar://problem/3333744>: Safari prints page with 
index 57d78c2..01481b8 100644 (file)
     [self addData:data];
 }
 
-- (id <WebCoreResourceHandle>)startLoadingResource:(id <WebCoreResourceLoader>)resourceLoader withURL:(NSURL *)URL
+- (id <WebCoreResourceHandle>)startLoadingResource:(id <WebCoreResourceLoader>)resourceLoader withURL:(NSURL *)URL customHeaders:(NSDictionary *)customHeaders
 {
     // If we are no longer attached to a WebView, this must be an attempted load from an
     // onUnload handler, so let's just block it.
 
     return [WebSubresourceClient startLoadingResource:resourceLoader
                                               withURL:URL
+                                       customHeaders:customHeaders
                                              referrer:[self referrer]
                                         forDataSource:[self dataSource]];
 }
 
-- (id <WebCoreResourceHandle>)startLoadingResource:(id <WebCoreResourceLoader>)resourceLoader withURL:(NSURL *)URL postData:(NSData *)data
+- (id <WebCoreResourceHandle>)startLoadingResource:(id <WebCoreResourceLoader>)resourceLoader withURL:(NSURL *)URL customHeaders:(NSDictionary *)customHeaders postData:(NSData *)data
 {
     // If we are no longer attached to a WebView, this must be an attempted load from an
     // onUnload handler, so let's just block it.
 
     return [WebSubresourceClient startLoadingResource:resourceLoader
                                               withURL:URL
+                                       customHeaders:customHeaders
                                             postData:data
                                              referrer:[self referrer]
                                         forDataSource:[self dataSource]];
index b27f663..9d7d420 100644 (file)
 }
 
 + (WebSubresourceClient *)startLoadingResource:(id <WebCoreResourceLoader>)rLoader
-    withURL:(NSURL *)URL referrer:(NSString *)referrer forDataSource:(WebDataSource *)source;
+                                       withURL:(NSURL *)URL 
+                                 customHeaders:(NSDictionary *)customHeaders
+                                      referrer:(NSString *)referrer 
+                                 forDataSource:(WebDataSource *)source;
 
 + (WebSubresourceClient *)startLoadingResource:(id <WebCoreResourceLoader>)rLoader
-    withURL:(NSURL *)URL postData:(NSData *)data referrer:(NSString *)referrer forDataSource:(WebDataSource *)source;
+                                       withURL:(NSURL *)URL 
+                                 customHeaders:(NSDictionary *)customHeaders
+                                      postData:(NSData *)data 
+                                      referrer:(NSString *)referrer 
+                                 forDataSource:(WebDataSource *)source;
 
 @end
index 4aad3c5..ffa6d69 100644 (file)
@@ -41,6 +41,7 @@
 
 + (WebSubresourceClient *)startLoadingResource:(id <WebCoreResourceLoader>)rLoader
                                   withRequest:(NSMutableURLRequest *)newRequest
+                                 customHeaders:(NSDictionary *)customHeaders
                                      referrer:(NSString *)referrer 
                                 forDataSource:(WebDataSource *)source
 {
     
     [source _addSubresourceClient:client];
 
+
+    NSEnumerator *e = [customHeaders keyEnumerator];
+    NSString *key;
+    while ((key = (NSString *)[e nextObject]) != nil) {
+       [newRequest addValue:[customHeaders objectForKey:key] forHTTPHeaderField:key];
+    }
+
     [newRequest setCachePolicy:[[source request] cachePolicy]];
     [newRequest setHTTPReferrer:referrer];
     
 }
 
 + (WebSubresourceClient *)startLoadingResource:(id <WebCoreResourceLoader>)rLoader
-    withURL:(NSURL *)URL referrer:(NSString *)referrer forDataSource:(WebDataSource *)source
+                                      withURL:(NSURL *)URL
+                                customHeaders:(NSDictionary *)customHeaders
+                                     referrer:(NSString *)referrer
+                                forDataSource:(WebDataSource *)source
 {
     NSMutableURLRequest *newRequest = [[NSMutableURLRequest alloc] initWithURL:URL];
-    WebSubresourceClient *client = [self startLoadingResource:rLoader withRequest:newRequest referrer:referrer forDataSource:source];
+    WebSubresourceClient *client = [self startLoadingResource:rLoader withRequest:newRequest customHeaders:customHeaders referrer:referrer forDataSource:source];
     [newRequest release];
 
     return client;
 }
 
 + (WebSubresourceClient *)startLoadingResource:(id <WebCoreResourceLoader>)rLoader
-    withURL:(NSURL *)URL postData:(NSData *)data referrer:(NSString *)referrer forDataSource:(WebDataSource *)source
+                                      withURL:(NSURL *)URL
+                                customHeaders:(NSDictionary *)customHeaders
+                                     postData:(NSData *)data
+                                     referrer:(NSString *)referrer
+                                forDataSource:(WebDataSource *)source
 {
     NSMutableURLRequest *newRequest = [[NSMutableURLRequest alloc] initWithURL:URL];
     [newRequest setHTTPMethod:@"POST"];
     [newRequest setHTTPBody:data];
-    WebSubresourceClient *client = [self startLoadingResource:rLoader withRequest:newRequest referrer:referrer forDataSource:source];
+    WebSubresourceClient *client = [self startLoadingResource:rLoader withRequest:newRequest customHeaders:customHeaders referrer:referrer forDataSource:source];
     [newRequest release];
 
     return client;
index b27f663..9d7d420 100644 (file)
 }
 
 + (WebSubresourceClient *)startLoadingResource:(id <WebCoreResourceLoader>)rLoader
-    withURL:(NSURL *)URL referrer:(NSString *)referrer forDataSource:(WebDataSource *)source;
+                                       withURL:(NSURL *)URL 
+                                 customHeaders:(NSDictionary *)customHeaders
+                                      referrer:(NSString *)referrer 
+                                 forDataSource:(WebDataSource *)source;
 
 + (WebSubresourceClient *)startLoadingResource:(id <WebCoreResourceLoader>)rLoader
-    withURL:(NSURL *)URL postData:(NSData *)data referrer:(NSString *)referrer forDataSource:(WebDataSource *)source;
+                                       withURL:(NSURL *)URL 
+                                 customHeaders:(NSDictionary *)customHeaders
+                                      postData:(NSData *)data 
+                                      referrer:(NSString *)referrer 
+                                 forDataSource:(WebDataSource *)source;
 
 @end
index 4aad3c5..ffa6d69 100644 (file)
@@ -41,6 +41,7 @@
 
 + (WebSubresourceClient *)startLoadingResource:(id <WebCoreResourceLoader>)rLoader
                                   withRequest:(NSMutableURLRequest *)newRequest
+                                 customHeaders:(NSDictionary *)customHeaders
                                      referrer:(NSString *)referrer 
                                 forDataSource:(WebDataSource *)source
 {
     
     [source _addSubresourceClient:client];
 
+
+    NSEnumerator *e = [customHeaders keyEnumerator];
+    NSString *key;
+    while ((key = (NSString *)[e nextObject]) != nil) {
+       [newRequest addValue:[customHeaders objectForKey:key] forHTTPHeaderField:key];
+    }
+
     [newRequest setCachePolicy:[[source request] cachePolicy]];
     [newRequest setHTTPReferrer:referrer];
     
 }
 
 + (WebSubresourceClient *)startLoadingResource:(id <WebCoreResourceLoader>)rLoader
-    withURL:(NSURL *)URL referrer:(NSString *)referrer forDataSource:(WebDataSource *)source
+                                      withURL:(NSURL *)URL
+                                customHeaders:(NSDictionary *)customHeaders
+                                     referrer:(NSString *)referrer
+                                forDataSource:(WebDataSource *)source
 {
     NSMutableURLRequest *newRequest = [[NSMutableURLRequest alloc] initWithURL:URL];
-    WebSubresourceClient *client = [self startLoadingResource:rLoader withRequest:newRequest referrer:referrer forDataSource:source];
+    WebSubresourceClient *client = [self startLoadingResource:rLoader withRequest:newRequest customHeaders:customHeaders referrer:referrer forDataSource:source];
     [newRequest release];
 
     return client;
 }
 
 + (WebSubresourceClient *)startLoadingResource:(id <WebCoreResourceLoader>)rLoader
-    withURL:(NSURL *)URL postData:(NSData *)data referrer:(NSString *)referrer forDataSource:(WebDataSource *)source
+                                      withURL:(NSURL *)URL
+                                customHeaders:(NSDictionary *)customHeaders
+                                     postData:(NSData *)data
+                                     referrer:(NSString *)referrer
+                                forDataSource:(WebDataSource *)source
 {
     NSMutableURLRequest *newRequest = [[NSMutableURLRequest alloc] initWithURL:URL];
     [newRequest setHTTPMethod:@"POST"];
     [newRequest setHTTPBody:data];
-    WebSubresourceClient *client = [self startLoadingResource:rLoader withRequest:newRequest referrer:referrer forDataSource:source];
+    WebSubresourceClient *client = [self startLoadingResource:rLoader withRequest:newRequest customHeaders:customHeaders referrer:referrer forDataSource:source];
     [newRequest release];
 
     return client;