Commit 6f017c14 authored by ggaren's avatar ggaren

JavaScriptCore:

        Reviewed by Darin Adler.

        http://bugs.webkit.org/show_bug.cgi?id=13029
        rdar://problem/4994849
        Bug 13029: Permit NPAPI plug-ins to see HTTP response headers.
        This doesn't actually change JavaScriptCore, but that's where npapi.h is.

        * bindings/npapi.h:
        Add headers member to NPStream struct.  Also increase NP_VERSION_MINOR to 18.
        Increasing to >= 17 allows plug-ins to safely detect whether to look for
        NPStream::headers.  Increasing from 17 to 18 reflects presence of NPObject
        enumeration, which was added in a prior patch, and which has been agreed to
        constitute version 18 by the plugin-futures list.  Also add other missing
        bits of npapi.h to catch up from 14 to 18.  This includes features that are
        not implemented in WebKit, but those are safely stubbed.

LayoutTests:

        Reviewed by Darin Adler.

        http://bugs.webkit.org/show_bug.cgi?id=13029
        rdar://problem/4994849
        Bug 13029: Permit NPAPI plug-ins to see HTTP response headers.

        * http/tests/plugins/npapi-response-headers-expected.txt: Added.
        * http/tests/plugins/npapi-response-headers.html: Added.
        * http/tests/plugins/resources/load-me-1.txt: Added.
        * http/tests/plugins/resources/load-me-2.txt: Added.

WebKit:

        Reviewed by Darin Adler.

        http://bugs.webkit.org/show_bug.cgi?id=13029
        rdar://problem/4994849
        Bug 13029: Permit NPAPI plug-ins to see HTTP response headers.

        * Plugins/WebBaseNetscapePluginStream.h: declarations.
        * Plugins/WebBaseNetscapePluginStream.mm: main implementation.
        (-[WebBaseNetscapePluginStream dealloc]): cleanup.
        (-[WebBaseNetscapePluginStream finalize]): cleanup.
        (-[WebBaseNetscapePluginStream startStreamResponseURL:expectedContentLength:lastModifiedDate:MIMEType:headers:]):
        Pass headers along.
        (-[WebBaseNetscapePluginStream startStreamWithResponse:]):
        Main work is here.  Extract headers from NSHTTPURLResponse object into a byte sequence.
        See comments here about how it would be nice to have low-level access to the HTTP response.
        (-[WebBaseNetscapePluginStream _destroyStream]): cleanup.
        * Plugins/WebBaseNetscapePluginView.mm:
        (-[WebBaseNetscapePluginView evaluateJavaScriptPluginRequest:]):
        Conform to new startStream params.  Not applicable here, pass nil.

WebKitTools:

        Reviewed by Darin Adler.

        http://bugs.webkit.org/show_bug.cgi?id=13029
        rdar://problem/4994849
        Bug 13029: Permit NPAPI plug-ins to see HTTP response headers.
        Changes in WebKitTools are only for the NPAPI test plugin.

        * DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.c: main test logic.
        (pluginInvoke): support null window argument for NPStream creation.
        (pluginAllocate): initialization.
        (pluginDeallocate): cleanup.
        (handleCallback): add second JS callback arg: header dump.
        (notifyStream): added; hook from NPP_NewStream to record headers.
        * DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.h: declarations.
        * DumpRenderTree/TestNetscapePlugIn.subproj/main.c: call new header hook.
        (NPP_NewStream): call new header hook.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@20867 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 6709604f
2007-04-12 Deneb Meketa <dmeketa@adobe.com>
Reviewed by Darin Adler.
http://bugs.webkit.org/show_bug.cgi?id=13029
rdar://problem/4994849
Bug 13029: Permit NPAPI plug-ins to see HTTP response headers.
This doesn't actually change JavaScriptCore, but that's where npapi.h is.
* bindings/npapi.h:
Add headers member to NPStream struct. Also increase NP_VERSION_MINOR to 18.
Increasing to >= 17 allows plug-ins to safely detect whether to look for
NPStream::headers. Increasing from 17 to 18 reflects presence of NPObject
enumeration, which was added in a prior patch, and which has been agreed to
constitute version 18 by the plugin-futures list. Also add other missing
bits of npapi.h to catch up from 14 to 18. This includes features that are
not implemented in WebKit, but those are safely stubbed.
2007-04-10 Geoffrey Garen <ggaren@apple.com>
Reviewed by Mark Rowe.
......
......@@ -1389,13 +1389,11 @@
0867D690FE84028FC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 149C277108902AFE008A9EFC /* Build configuration list for PBXProject "JavaScriptCore" */;
compatibilityVersion = "Xcode 2.4";
hasScannedForEncodings = 1;
mainGroup = 0867D691FE84028FC02AAC07 /* JavaScriptCore */;
productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
projectDirPath = "";
projectRoot = "";
shouldCheckCompatibility = 1;
targets = (
932F5BE30822A1C700736975 /* All */,
932F5B3E0822A1C700736975 /* JavaScriptCore */,
......
......@@ -104,7 +104,7 @@
/*----------------------------------------------------------------------*/
#define NP_VERSION_MAJOR 0
#define NP_VERSION_MINOR 17
#define NP_VERSION_MINOR 18
......@@ -187,6 +187,16 @@ typedef struct _NPStream
uint32 end;
uint32 lastmodified;
void* notifyData;
const char* headers; /* Response headers from host.
* Exists only for >= NPVERS_HAS_RESPONSE_HEADERS.
* Used for HTTP only; NULL for non-HTTP.
* Available from NPP_NewStream onwards.
* Plugin should copy this data before storing it.
* Includes HTTP status line and all headers,
* preferably verbatim as received from server,
* headers formatted as in HTTP ("Header: Value"),
* and newlines (\n, NOT \r\n) separating lines.
* Terminated by \n\0 (NOT \n\n\0). */
} NPStream;
......@@ -314,7 +324,13 @@ typedef enum {
NPPVpluginNeedsXEmbed = 14, /* Not implemented in WebKit */
/* Get the NPObject for scripting the plugin. */
NPPVpluginScriptableNPObject = 15
NPPVpluginScriptableNPObject = 15,
/* Get the plugin value (as \0-terminated UTF-8 string data) for
* form submission if the plugin is part of a form. Use
* NPN_MemAlloc() to allocate memory for the string data.
*/
NPPVformValue = 16 /* Not implemented in WebKit */
} NPPVariable;
/*
......@@ -587,6 +603,12 @@ typedef struct NP_Port
#define NPVERS_WIN16_HAS_LIVECONNECT 9
#define NPVERS_68K_HAS_LIVECONNECT 11
#define NPVERS_HAS_WINDOWLESS 11
#define NPVERS_HAS_XPCONNECT_SCRIPTING 13 /* Not implemented in WebKit */
#define NPVERS_HAS_NPRUNTIME_SCRIPTING 14
#define NPVERS_HAS_FORM_VALUES 15 /* Not implemented in WebKit; see bug 13061 */
#define NPVERS_HAS_POPUPS_ENABLED_STATE 16 /* Not implemented in WebKit */
#define NPVERS_HAS_RESPONSE_HEADERS 17
#define NPVERS_HAS_NPOBJECT_ENUM 18
/*----------------------------------------------------------------------*/
......
2007-04-12 Deneb Meketa <dmeketa@adobe.com>
Reviewed by Darin Adler.
http://bugs.webkit.org/show_bug.cgi?id=13029
rdar://problem/4994849
Bug 13029: Permit NPAPI plug-ins to see HTTP response headers.
* http/tests/plugins/npapi-response-headers-expected.txt: Added.
* http/tests/plugins/npapi-response-headers.html: Added.
* http/tests/plugins/resources/load-me-1.txt: Added.
* http/tests/plugins/resources/load-me-2.txt: Added.
2007-04-12 Justin Garcia <justin.garcia@apple.com>
Reviewed by darin
Test for bug 13029: Permit NPAPI plug-ins to see HTTP response headers.
Expected result below is two HTTP response extracts, one for the initial stream specified in the "src" attribute, the other for an NPN_GetURLNotify request. Each block should contain the URL; the status line, which should say "HTTP 200 OK"; and the MIME-type, which should say "Content-Type: text/plain".
----------
http://[varies, not being tested]/plugins/resources/load-me-1.txt
HTTP 200 OK
Content-Type: text/plain
----------
http://[varies, not being tested]/plugins/resources/load-me-2.txt
HTTP 200 OK
Content-Type: text/plain
<html>
<head>
<script>
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.waitUntilDone();
}
var res1, res2;
function test()
{
try {
res1 = document.getElementById("result1");
res2 = document.getElementById("result2");
plg.getURLNotify("/plugins/resources/load-me-2.txt", null, "callback");
} catch (ex) {
showErr("Exception: " + ex.description);
if (window.layoutTestController)
layoutTestController.notifyDone();
}
}
function callback(errCode, streamDump)
{
var parse = parseStreamDump(streamDump);
if (parse.err)
showErr(parse.err);
else {
res1.innerHTML = newlinesToHTML(parse.res1);
res2.innerHTML = newlinesToHTML(parse.res2);
}
if (window.layoutTestController)
layoutTestController.notifyDone();
}
// Format passed by plugin: four fields separated by \n\n:
// First URL; first header block; last URL; last header block.
function parseStreamDump(streamDump)
{
var rtn = {};
if (typeof streamDump == "string" || ((typeof streamDump == "object") && (streamDump.constructor == String))) {
var parts = streamDump.split("\n\n");
if (parts.length >= 4) {
rtn.res1 = genericURL(parts[0]) + "\n" + parseHeaders(parts[1]);
rtn.res2 = genericURL(parts[2]) + "\n" + parseHeaders(parts[3]);
} else
rtn.err = "streamDump from plugin does not have expected format";
} else
rtn.err = "streamDump from plugin is not a string: " + streamDump;
return rtn;
}
function showErr(err)
{
res1.innerHTML = "FAILED - " + err;
res2.innerHTML = "";
}
function newlinesToHTML(str)
{
return str.replace(/\n/g, "<br>");
}
function genericURL(url)
{
return url.replace(/^(http:\/\/)[^\/]+/, "$1[varies, not being tested]");
}
function parseHeaders(hdrs)
{
var parts = hdrs.split("\n");
var rtn = parts[0] + "\n";
for (var i = 0; i < parts.length; i++)
if (parts[i].match(/^Content-Type:/))
rtn += parts[i];
return rtn;
}
</script>
</head>
<body onload="test()">
<embed name="plg" type="application/x-webkit-test-netscape" src="/plugins/resources/load-me-1.txt"></embed>
<p>Test for <a href="http://bugzilla.opendarwin.org/show_bug.cgi?id=13029">bug 13029<a/>:
Permit NPAPI plug-ins to see HTTP response headers.</p>
<p>Expected result below is two HTTP response extracts, one for the initial stream specified in the "src"
attribute, the other for an NPN_GetURLNotify request. Each block should contain the URL; the status line,
which should say "HTTP 200 OK"; and the MIME-type, which should say "Content-Type: text/plain".</p>
<p>----------</p>
<p id="result1">Running test, result should appear here in a very short time...</p>
<p>----------</p>
<p id="result2">Running test, result should appear here in a very short time...</p>
</body>
</html>
It's a lonely existence being a test file.
You're welcome.
Oh yeah.
Nobody lookin' at me.
Just chillin'.
Test file.
Oh yeah.
......@@ -11274,7 +11274,6 @@
0867D690FE84028FC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 149C284308902B11008A9EFC /* Build configuration list for PBXProject "WebCore" */;
compatibilityVersion = "Xcode 2.4";
hasScannedForEncodings = 1;
knownRegions = (
English,
......@@ -11289,7 +11288,6 @@
productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
projectDirPath = "";
projectRoot = "";
shouldCheckCompatibility = 1;
targets = (
93F198A508245E59001E9ABC /* WebCore */,
DD041FBE09D9DDBE0010AF2A /* Derived Sources */,
2007-04-12 Deneb Meketa <dmeketa@adobe.com>
Reviewed by Darin Adler.
http://bugs.webkit.org/show_bug.cgi?id=13029
rdar://problem/4994849
Bug 13029: Permit NPAPI plug-ins to see HTTP response headers.
* Plugins/WebBaseNetscapePluginStream.h: declarations.
* Plugins/WebBaseNetscapePluginStream.mm: main implementation.
(-[WebBaseNetscapePluginStream dealloc]): cleanup.
(-[WebBaseNetscapePluginStream finalize]): cleanup.
(-[WebBaseNetscapePluginStream startStreamResponseURL:expectedContentLength:lastModifiedDate:MIMEType:headers:]):
Pass headers along.
(-[WebBaseNetscapePluginStream startStreamWithResponse:]):
Main work is here. Extract headers from NSHTTPURLResponse object into a byte sequence.
See comments here about how it would be nice to have low-level access to the HTTP response.
(-[WebBaseNetscapePluginStream _destroyStream]): cleanup.
* Plugins/WebBaseNetscapePluginView.mm:
(-[WebBaseNetscapePluginView evaluateJavaScriptPluginRequest:]):
Conform to new startStream params. Not applicable here, pass nil.
2007-04-12 Brady Eidson <beidson@apple.com>
Build fix for case sensitive file systems
......
......@@ -48,6 +48,7 @@
char *path;
BOOL sendNotification;
void *notifyData;
char *headers;
WebBaseNetscapePluginView *pluginView;
NPReason reason;
BOOL isTerminated;
......@@ -80,7 +81,8 @@
- (void)startStreamResponseURL:(NSURL *)theResponseURL
expectedContentLength:(long long)expectedContentLength
lastModifiedDate:(NSDate *)lastModifiedDate
MIMEType:(NSString *)MIMEType;
MIMEType:(NSString *)MIMEType
headers:(NSData *)theHeaders;
// cancelLoadWithError cancels the NSURLConnection and informs WebKit of the load error.
// This method is overriden by subclasses.
......
......@@ -141,6 +141,7 @@ static StreamMap& streams()
free((void *)stream.url);
free(path);
free(headers);
streams().remove(&stream);
......@@ -158,6 +159,7 @@ static StreamMap& streams()
free((void *)stream.url);
free(path);
free(headers);
streams().remove(&stream);
......@@ -228,6 +230,7 @@ static StreamMap& streams()
expectedContentLength:(long long)expectedContentLength
lastModifiedDate:(NSDate *)lastModifiedDate
MIMEType:(NSString *)theMIMEType
headers:(NSData *)theHeaders
{
ASSERT(!isTerminated);
......@@ -241,6 +244,14 @@ static StreamMap& streams()
stream.end = expectedContentLength > 0 ? (uint32)expectedContentLength : 0;
stream.lastmodified = (uint32)[lastModifiedDate timeIntervalSince1970];
stream.notifyData = notifyData;
if (theHeaders) {
unsigned len = [theHeaders length];
headers = (char*) malloc(len + 1);
[theHeaders getBytes:headers];
headers[len] = 0;
stream.headers = headers;
}
transferMode = NP_NORMAL;
offset = 0;
......@@ -282,10 +293,50 @@ static StreamMap& streams()
- (void)startStreamWithResponse:(NSURLResponse *)r
{
NSMutableData *theHeaders = nil;
if ([r isKindOfClass:[NSHTTPURLResponse class]]) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)r;
theHeaders = [NSMutableData dataWithCapacity:1024];
// FIXME: it would be nice to be able to get the raw HTTP header block.
// This includes the HTTP version, the real status text,
// all headers in their original order and including duplicates,
// and all original bytes verbatim, rather than sent through Unicode translation.
// Unfortunately NSHTTPURLResponse doesn't provide access at that low a level.
[theHeaders appendBytes:"HTTP " length:5];
char statusStr[10];
snprintf(statusStr, sizeof(statusStr), "%d", [httpResponse statusCode]);
[theHeaders appendBytes:statusStr length:strlen(statusStr)];
[theHeaders appendBytes:" OK\n" length:4];
// HACK: pass the headers through as UTF-8.
// This is not the intended behavior; we're supposed to pass original bytes verbatim.
// But we don't have the original bytes, we have NSStrings built by the URL loading system.
// It hopefully shouldn't matter, since RFC2616/RFC822 require ASCII-only headers,
// but surely someone out there is using non-ASCII characters, and hopefully UTF-8 is adequate here.
// It seems better than NSASCIIStringEncoding, which will lose information if non-ASCII is used.
NSDictionary *headerDict = [httpResponse allHeaderFields];
NSArray *keys = [[headerDict allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
NSEnumerator *i = [keys objectEnumerator];
NSString *k;
while ((k = [i nextObject]) != nil) {
NSString *v = [headerDict objectForKey:k];
[theHeaders appendData:[k dataUsingEncoding:NSUTF8StringEncoding]];
[theHeaders appendBytes:": " length:2];
[theHeaders appendData:[v dataUsingEncoding:NSUTF8StringEncoding]];
[theHeaders appendBytes:"\n" length:1];
}
// startStreamResponseURL:... will null-terminate.
}
[self startStreamResponseURL:[r URL]
expectedContentLength:[r expectedContentLength]
lastModifiedDate:WKGetNSURLResponseLastModifiedDate(r)
MIMEType:[r MIMEType]];
MIMEType:[r MIMEType]
headers:theHeaders];
}
- (void)_destroyStream
......@@ -331,6 +382,10 @@ static StreamMap& streams()
[pv didCallPlugInFunction];
LOG(Plugins, "NPP_DestroyStream responseURL=%@ error=%d", responseURL, npErr);
free(headers);
headers = NULL;
stream.headers = NULL;
stream.ndata = nil;
if (isTerminated)
......
......@@ -2042,7 +2042,8 @@ static OSStatus TSMEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEve
[stream startStreamResponseURL:URL
expectedContentLength:[JSData length]
lastModifiedDate:nil
MIMEType:@"text/plain"];
MIMEType:@"text/plain"
headers:nil];
[stream receivedData:JSData];
[stream finishedLoadingWithData:JSData];
[stream release];
......
2007-04-12 Deneb Meketa <dmeketa@adobe.com>
Reviewed by Darin Adler.
http://bugs.webkit.org/show_bug.cgi?id=13029
rdar://problem/4994849
Bug 13029: Permit NPAPI plug-ins to see HTTP response headers.
Changes in WebKitTools are only for the NPAPI test plugin.
* DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.c: main test logic.
(pluginInvoke): support null window argument for NPStream creation.
(pluginAllocate): initialization.
(pluginDeallocate): cleanup.
(handleCallback): add second JS callback arg: header dump.
(notifyStream): added; hook from NPP_NewStream to record headers.
* DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.h: declarations.
* DumpRenderTree/TestNetscapePlugIn.subproj/main.c: call new header hook.
(NPP_NewStream): call new header hook.
2007-04-09 Geoffrey Garen <ggaren@apple.com>
Reviewed by Maciej Stachowiak.
......
......@@ -241,9 +241,12 @@ static bool pluginInvoke(NPObject *header, NPIdentifier name, const NPVariant *a
VOID_TO_NPVARIANT(*result);
return true;
} else if (name == pluginMethodIdentifiers[ID_TEST_GET_URL_NOTIFY]) {
if (argCount == 3 && NPVARIANT_IS_STRING(args[0]) && NPVARIANT_IS_STRING(args[1]) && NPVARIANT_IS_STRING(args[2])) {
if (argCount == 3
&& NPVARIANT_IS_STRING(args[0])
&& (NPVARIANT_IS_STRING(args[1]) || NPVARIANT_IS_NULL(args[1]))
&& NPVARIANT_IS_STRING(args[2])) {
NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
NPUTF8* targetString = createCStringFromNPVariant(&args[1]);
NPUTF8* targetString = (NPVARIANT_IS_STRING(args[1]) ? createCStringFromNPVariant(&args[1]) : NULL);
NPUTF8* callbackString = createCStringFromNPVariant(&args[2]);
NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString);
......@@ -332,6 +335,11 @@ static NPObject *pluginAllocate(NPP npp, NPClass *theClass)
newInstance->logDestroy = FALSE;
newInstance->stream = 0;
newInstance->firstUrl = NULL;
newInstance->firstHeaders = NULL;
newInstance->lastUrl = NULL;
newInstance->lastHeaders = NULL;
return (NPObject *)newInstance;
}
......@@ -340,15 +348,20 @@ static void pluginDeallocate(NPObject *header)
PluginObject* obj = (PluginObject*)header;
browser->releaseobject(obj->testObject);
free(header);
free(obj->firstUrl);
free(obj->firstHeaders);
free(obj->lastUrl);
free(obj->lastHeaders);
free(obj);
}
void handleCallback(PluginObject* object, const char *url, NPReason reason, void *notifyData)
{
assert(object);
NPVariant args[1];
NPVariant args[2];
NPObject *windowScriptObject;
browser->getvalue(object->npp, NPNVWindowNPObject, &windowScriptObject);
......@@ -357,7 +370,40 @@ void handleCallback(PluginObject* object, const char *url, NPReason reason, void
INT32_TO_NPVARIANT(reason, args[0]);
char *strHdr = NULL;
if (object->firstUrl && object->firstHeaders && object->lastUrl && object->lastHeaders) {
// Format expected by JavaScript validator: four fields separated by \n\n:
// First URL; first header block; last URL; last header block.
// Note that header blocks already end with \n due to how NPStream::headers works.
int len = strlen(object->firstUrl) + 2
+ strlen(object->firstHeaders) + 1
+ strlen(object->lastUrl) + 2
+ strlen(object->lastHeaders) + 1;
strHdr = malloc(len + 1);
snprintf(strHdr, len + 1, "%s\n\n%s\n%s\n\n%s\n",
object->firstUrl, object->firstHeaders, object->lastUrl, object->lastHeaders);
STRINGN_TO_NPVARIANT(strHdr, len, args[1]);
} else
NULL_TO_NPVARIANT(args[1]);
NPVariant browserResult;
browser->invoke(object->npp, windowScriptObject, callbackIdentifier, args, 1, &browserResult);
browser->invoke(object->npp, windowScriptObject, callbackIdentifier, args, 2, &browserResult);
browser->releasevariantvalue(&browserResult);
free(strHdr);
}
void notifyStream(PluginObject* object, const char *url, const char *headers)
{
if (object->firstUrl == NULL) {
if (url)
object->firstUrl = strdup(url);
if (headers)
object->firstHeaders = strdup(headers);
} else {
free(object->lastUrl);
free(object->lastHeaders);
object->lastUrl = (url ? strdup(url) : NULL);
object->lastHeaders = (headers ? strdup(headers) : NULL);
}
}
......@@ -43,7 +43,12 @@ typedef struct {
NPObject* testObject;
NPStream* stream;
char* onStreamLoad;
char* firstUrl;
char* firstHeaders;
char* lastUrl;
char* lastHeaders;
} PluginObject;
extern NPClass *getPluginClass(void);
extern void handleCallback(PluginObject* object, const char *url, NPReason reason, void *notifyData);
extern void notifyStream(PluginObject* object, const char *url, const char *headers);
......@@ -114,6 +114,9 @@ NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, NPBool se
obj->stream = stream;
*stype = NP_ASFILEONLY;
if (obj && (browser->version >= NPVERS_HAS_RESPONSE_HEADERS))
notifyStream(obj, stream->url, stream->headers);
if (obj->onStreamLoad) {
NPObject *windowScriptObject;
browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment