From 807bf6b7a9353cc60e27b35be8fa779a6091ded3 Mon Sep 17 00:00:00 2001 From: "edburns%acm.org" Date: Mon, 28 Feb 2005 17:15:45 +0000 Subject: [PATCH] This checkin enables finding out the request method and response status of a URL_LOAD event. I'm still working on getting the request body via the nsIUploadChannel interface. Next step will be to get that working. I'm currently running into problems where the END_URL event for a POST doesn't have a status. I think this is because I'm using the Navigation.post() method rather than simulating a user post by pressing a form submit button. A classes_spec/org/mozilla/webclient/impl/wrapper_native/NativeInputStream.java A src_moz/NativeInputStreamImpl.cpp - Class to enable reading the post body from the request. M build.xml - add NativeInputStream to JNI generation M classes_spec/org/mozilla/webclient/PageInfoListener.java *

This {@link DocumentLoadListener} subclass adds the ability to get * detailed information on each event.

* *

The eventData property of the * DocumentLoadEvent instance will be a * java.util.Map. The following entries may be present in * this map for the following *_EVENT_MASK types in * DocumentLoadEvent.

* *
* *
For all *_EVENT_MASK types
* *

the map will contain an entry under the key "URI" * without the quotes. This will be the fully qualified URI for the * event.

* *
For START_URL_LOAD type
* *

The map will contain an entry under the key * "method" without the quotes. This will be the request * method for this event. The map will also contain an entry under the * key "headers". This entry will be a * java.util.Map of all the request headers.

* *
For END_URL_LOAD type
* *

The map will contain an entry under the key * "method" without the quotes. This will be the request * method for this event. The map will contain an entry under the key * "status" without the quotes. This will be the response * status string from the server, such as "200 OK". The * map will also contain an entry under the key "headers". * This entry will be a java.util.Map of all the response * headers.

* *
M src_moz/EmbedProgress.cpp - leverage nsIHttpChannel methods to get request method, response status, and post body. M src_moz/Makefile.in - add NativeInputStream M src_share/jni_util.cpp M src_share/jni_util.h - new constants - add variant of ThrowExceptionToJava that takes the exception class name. M test/automated/src/classes/org/mozilla/webclient/DocumentLoadListenerTest.java - new test content. Post related content commented out. --- java/webclient/build.xml | 2 +- .../mozilla/webclient/PageInfoListener.java | 43 +++++-- .../wrapper_native/NativeInputStream.java | 98 ++++++++++++++++ java/webclient/src_moz/EmbedProgress.cpp | 108 ++++++++++++++++++ java/webclient/src_moz/Makefile.in | 1 + .../src_moz/NativeInputStreamImpl.cpp | 107 +++++++++++++++++ java/webclient/src_share/jni_util.cpp | 26 ++++- java/webclient/src_share/jni_util.h | 5 + .../webclient/DocumentLoadListenerTest.java | 108 ++++++++++++++++-- 9 files changed, 479 insertions(+), 19 deletions(-) create mode 100644 java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/NativeInputStream.java create mode 100644 java/webclient/src_moz/NativeInputStreamImpl.cpp diff --git a/java/webclient/build.xml b/java/webclient/build.xml index 15be9c66833..ae4ca4f08d4 100644 --- a/java/webclient/build.xml +++ b/java/webclient/build.xml @@ -124,7 +124,7 @@ + class="org.mozilla.webclient.impl.wrapper_native.BookmarksImpl,org.mozilla.webclient.impl.wrapper_native.ProfileManagerImpl,org.mozilla.webclient.impl.wrapper_native.PreferencesImpl,org.mozilla.webclient.impl.wrapper_native.CurrentPageImpl,org.mozilla.webclient.impl.wrapper_native.HistoryImpl,org.mozilla.webclient.impl.wrapper_native.WrapperFactoryImpl,org.mozilla.webclient.impl.wrapper_native.NavigationImpl,org.mozilla.webclient.impl.wrapper_native.RDFEnumeration,org.mozilla.webclient.impl.wrapper_native.RDFTreeNode,org.mozilla.webclient.impl.wrapper_native.ISupportsPeer,org.mozilla.webclient.impl.wrapper_native.WindowControlImpl,org.mozilla.webclient.impl.wrapper_native.NativeEventThread,org.mozilla.webclient.impl.wrapper_native.EventRegistrationImpl,org.mozilla.webclient.impl.wrapper_native.NativeInputStream"> diff --git a/java/webclient/classes_spec/org/mozilla/webclient/PageInfoListener.java b/java/webclient/classes_spec/org/mozilla/webclient/PageInfoListener.java index 5129c6dd487..9cd15ce22c9 100644 --- a/java/webclient/classes_spec/org/mozilla/webclient/PageInfoListener.java +++ b/java/webclient/classes_spec/org/mozilla/webclient/PageInfoListener.java @@ -26,18 +26,41 @@ package org.mozilla.webclient; *

This {@link DocumentLoadListener} subclass adds the ability to get * detailed information on each event.

* - *

The eventDispatched() method is passed the same thing - * as in the {@link DocumentLoadListener}.

- * *

The eventData property of the * DocumentLoadEvent instance will be a - * java.util.Map. For the - * END_URL_LOAD_EVENT_MASK type in - * DocumentLoadEvent the map will contain an entry under - * the key "URI" without the quotes. This will be the - * fully qualified URI for the event. The map will also contain an - * entry under the key "headers". This entry will be a - * Map of all the response headers.

+ * java.util.Map. The following entries may be present in + * this map for the following *_EVENT_MASK types in + * DocumentLoadEvent.

+ * + *
+ * + *
For all *_EVENT_MASK types
+ * + *

the map will contain an entry under the key "URI" + * without the quotes. This will be the fully qualified URI for the + * event.

+ * + *
For START_URL_LOAD type
+ * + *

The map will contain an entry under the key + * "method" without the quotes. This will be the request + * method for this event. The map will also contain an entry under the + * key "headers". This entry will be a + * java.util.Map of all the request headers.

+ * + *
For END_URL_LOAD type
+ * + *

The map will contain an entry under the key + * "method" without the quotes. This will be the request + * method for this event. The map will contain an entry under the key + * "status" without the quotes. This will be the response + * status string from the server, such as "200 OK". The + * map will also contain an entry under the key "headers". + * This entry will be a java.util.Map of all the response + * headers.

+ * + *
+ * * */ diff --git a/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/NativeInputStream.java b/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/NativeInputStream.java new file mode 100644 index 00000000000..d95f6e086ab --- /dev/null +++ b/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/NativeInputStream.java @@ -0,0 +1,98 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is RaptorCanvas. + * + * The Initial Developer of the Original Code is Kirk Baker and + * Ian Wilkinson. Portions created by Kirk Baker and Ian Wilkinson are + * Copyright (C) 1999 Kirk Baker and Ian Wilkinson. All + * Rights Reserved. + * + * Contributor(s): Ed Burns + */ + +package org.mozilla.webclient.impl.wrapper_native; + +import java.io.InputStream; +import java.io.IOException; + +public class NativeInputStream extends InputStream { + + // + // relationship ivars + // + private int nativeInputStream = -1; + + // + // ctors and initializers + // + + public NativeInputStream(int nativeInputStream) { + this.nativeInputStream = nativeInputStream; + } + + // + // Methods from InputStream + // + + public int read() throws IOException { + byte result[] = {(byte) -1}; + read(result); + return (int) result[0]; + } + + public int read(byte[] b, int off, int len) throws IOException { + if (-1 == nativeInputStream) { + throw new IOException("No NativeInputStream"); + } + return nativeRead(nativeInputStream, b, off, len); + } + + public long skip(long n) throws IOException { + throw new UnsupportedOperationException(); + } + + public int available() throws IOException { + if (-1 == nativeInputStream) { + throw new IOException("No NativeInputStream"); + } + return nativeAvailable(nativeInputStream); + } + + public void close() throws IOException { + if (-1 == nativeInputStream) { + throw new IOException("No NativeInputStream"); + } + nativeClose(nativeInputStream); + nativeInputStream = -1; + } + + public void mark(int readlimit) { + throw new UnsupportedOperationException(); + } + + public void reset() throws IOException { + throw new UnsupportedOperationException(); + } + + public boolean markSupported() { + return false; + } + + private native int nativeRead(int nativeInputStream, byte[] b, int off, + int len) throws IOException; + + private native int nativeAvailable(int nativeInputStream) throws IOException; + + private native void nativeClose(int nativeClose) throws IOException; + + +} // end of class NativeInputStream diff --git a/java/webclient/src_moz/EmbedProgress.cpp b/java/webclient/src_moz/EmbedProgress.cpp index a50564304e6..9d68da2692d 100644 --- a/java/webclient/src_moz/EmbedProgress.cpp +++ b/java/webclient/src_moz/EmbedProgress.cpp @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include "nsIURI.h" @@ -104,6 +106,8 @@ EmbedProgress::OnStateChange(nsIWebProgress *aWebProgress, mOwner->ContentStateChange(); JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION); nsXPIDLCString uriString; + nsCAutoString cstr; + nsresult rv; RequestToURIString(aRequest, getter_Copies(uriString)); const char * uriCStr = (const char *) uriString; // don't report "about:" URL events. @@ -154,6 +158,67 @@ EmbedProgress::OnStateChange(nsIWebProgress *aWebProgress, (aStateFlags & STATE_STOP)) { PR_LOG(prLogModuleInfo, PR_LOG_DEBUG, ("EmbedProgress::OnStateChange: END_DOCUMENT_LOAD\n")); + if (channel && mCapturePageInfo) { + // store the request method + if (NS_SUCCEEDED(rv = channel->GetRequestMethod(cstr))) { + jstring methodJStr = (jstring) ::util_NewGlobalRef(env, + ::util_NewStringUTF(env, cstr.get())); + + ::util_StoreIntoPropertiesObject(env, properties, + METHOD_VALUE, methodJStr, + (jobject) + &(mOwner->GetWrapperFactory()->shareContext)); + } + // store the response status + PRUint32 responseStatus; + if (NS_SUCCEEDED(rv =channel->GetResponseStatus(&responseStatus))){ + if (NS_SUCCEEDED(rv=channel->GetResponseStatusText(cstr))) { + nsAutoString autoStatus; + autoStatus.AppendInt(responseStatus); + autoStatus.AppendWithConversion(" "); + autoStatus.AppendWithConversion(cstr.get()); + + jstring statusJStr = (jstring) ::util_NewGlobalRef(env, + ::util_NewString(env, autoStatus.get(), autoStatus.Length())); + + ::util_StoreIntoPropertiesObject(env, properties, + STATUS_VALUE, statusJStr, + (jobject) + &(mOwner->GetWrapperFactory()->shareContext)); + + } + } + + // If there is an upload stream, store it as well + nsCOMPtr upload = do_QueryInterface(channel); + if (upload) { + nsIInputStream *uploadStream = nsnull; + if (NS_SUCCEEDED(rv = upload->GetUploadStream(&uploadStream)) + && uploadStream) { + jint pStream; + jclass clazz; + jobject streamObj; + jmethodID jID; + pStream = (jint) uploadStream; + uploadStream->AddRef(); + if (clazz = env->FindClass("org/mozilla/webclient/impl/wrapper_native/NativeInputStream")) { + if (jID = env->GetMethodID(clazz, "", "(I)V")) { + if (streamObj = env->NewObject(clazz,jID,pStream)){ + if (streamObj = ::util_NewGlobalRef(env, + streamObj)){ + ::util_StoreIntoPropertiesObject(env, + properties, + REQUEST_BODY_VALUE, + streamObj, + (jobject) + &(mOwner->GetWrapperFactory()->shareContext)); + } + } + } + } + } + } + } util_SendEventToJava(nsnull, mEventRegistration, @@ -176,6 +241,17 @@ EmbedProgress::OnStateChange(nsIWebProgress *aWebProgress, &(mOwner->GetWrapperFactory()->shareContext)); channel->VisitRequestHeaders(visitor); delete visitor; + // store the request method + if (NS_SUCCEEDED(rv = channel->GetRequestMethod(cstr))) { + jstring methodJStr = (jstring) ::util_NewGlobalRef(env, + ::util_NewStringUTF(env, cstr.get())); + + ::util_StoreIntoPropertiesObject(env, properties, + METHOD_VALUE, methodJStr, + (jobject) + &(mOwner->GetWrapperFactory()->shareContext)); + } + } util_SendEventToJava(nsnull, @@ -190,12 +266,44 @@ EmbedProgress::OnStateChange(nsIWebProgress *aWebProgress, ("EmbedProgress::OnStateChange: END_URL_LOAD\n")); if (channel && mCapturePageInfo) { + // store the response headers HttpHeaderVisitorImpl *visitor = new HttpHeaderVisitorImpl(env, properties, (jobject) &(mOwner->GetWrapperFactory()->shareContext)); channel->VisitResponseHeaders(visitor); delete visitor; + // store the request method + if (NS_SUCCEEDED(rv = channel->GetRequestMethod(cstr))) { + jstring methodJStr = (jstring) ::util_NewGlobalRef(env, + ::util_NewStringUTF(env, cstr.get())); + + ::util_StoreIntoPropertiesObject(env, properties, + METHOD_VALUE, methodJStr, + (jobject) + &(mOwner->GetWrapperFactory()->shareContext)); + } + + // store the response status + PRUint32 responseStatus; + if (NS_SUCCEEDED(rv =channel->GetResponseStatus(&responseStatus))){ + if (NS_SUCCEEDED(rv=channel->GetResponseStatusText(cstr))) { + nsAutoString autoStatus; + autoStatus.AppendInt(responseStatus); + autoStatus.AppendWithConversion(" "); + autoStatus.AppendWithConversion(cstr.get()); + + jstring statusJStr = (jstring) ::util_NewGlobalRef(env, + ::util_NewString(env, autoStatus.get(), autoStatus.Length())); + + ::util_StoreIntoPropertiesObject(env, properties, + STATUS_VALUE, statusJStr, + (jobject) + &(mOwner->GetWrapperFactory()->shareContext)); + + } + } + } util_SendEventToJava(nsnull, diff --git a/java/webclient/src_moz/Makefile.in b/java/webclient/src_moz/Makefile.in index 37f8536b722..908e6c04ae8 100644 --- a/java/webclient/src_moz/Makefile.in +++ b/java/webclient/src_moz/Makefile.in @@ -100,6 +100,7 @@ CPPSRCS = \ nsActions.cpp \ NavigationActionEvents.cpp \ InputStreamShim.cpp \ + NativeInputStreamImpl.cpp \ CurrentPageImpl.cpp \ NativeBrowserControl.cpp \ NativeWrapperFactory.cpp \ diff --git a/java/webclient/src_moz/NativeInputStreamImpl.cpp b/java/webclient/src_moz/NativeInputStreamImpl.cpp new file mode 100644 index 00000000000..c255a8b66e7 --- /dev/null +++ b/java/webclient/src_moz/NativeInputStreamImpl.cpp @@ -0,0 +1,107 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is RaptorCanvas. + * + * The Initial Developer of the Original Code is Kirk Baker and + * Ian Wilkinson. Portions created by Kirk Baker and Ian Wilkinson are + * Copyright (C) 1999 Kirk Baker and Ian Wilkinson. All + * Rights Reserved. + * + * Contributor(s): Kirk Baker + * Ian Wilkinson + * Mark Lin + * Mark Goddard + * Ed Burns + * Ashutosh Kulkarni + * Kyle Yuan + */ + +/* + * NativeInputStreamImpl.cpp + */ + +#include "org_mozilla_webclient_impl_wrapper_0005fnative_NativeInputStream.h" + +#include +#include "ns_util.h" + +JNIEXPORT jint JNICALL Java_org_mozilla_webclient_impl_wrapper_1native_NativeInputStream_nativeRead +(JNIEnv *env, jobject obj, jint nativeInputStream, jbyteArray buf, jint off, + jint len) +{ + nsIInputStream *stream = (nsIInputStream *) nativeInputStream; + nsresult rv = NS_OK; + PRUint32 ret; + + char *cbuf = new char[len]; + jbyte *jbytes = new jbyte[len]; + int i = 0; + // initialize the array + for (i = 0; i < len; i++) { + cbuf[i] = 0; + jbytes[i] = 0; + } + // call the mozilla method + if (NS_SUCCEEDED(rv = stream->Read(cbuf, len, &ret))) { + // copy the chars to jbytes + for (i = 0; i < ret; i++) { + jbytes[i] = (jbyte) cbuf[i]; + } + // copy the jbytes to the return back to java + env->SetByteArrayRegion(buf, off, ret, jbytes); + } + else { + ::util_ThrowExceptionToJava(env, "java/io/IOException", + "can't Read from native Stream"); + } + + return (jint) ret; +} + +/* + * Class: org_mozilla_webclient_impl_wrapper_0005fnative_NativeInputStream + * Method: nativeAvailable + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_mozilla_webclient_impl_wrapper_1native_NativeInputStream_nativeAvailable +(JNIEnv *env, jobject obj, jint nativeInputStream) +{ + nsIInputStream *stream = (nsIInputStream *) nativeInputStream; + nsresult rv = NS_OK; + PRUint32 result = -1; + + if (NS_FAILED(rv = stream->Available(&result))) { + ::util_ThrowExceptionToJava(env, "java/io/IOException", + "can't get Available from native Stream"); + } + + return (jint) result; +} + +JNIEXPORT void JNICALL Java_org_mozilla_webclient_impl_wrapper_1native_NativeInputStream_nativeClose +(JNIEnv *env, jobject obj, jint nativeInputStream) +{ + nsIInputStream *stream = (nsIInputStream *) nativeInputStream; + nsresult rv = NS_OK; + PRUint32 result = -1; + + if (NS_SUCCEEDED(rv = stream->Close())) { + stream->Release(); + } + else { + ::util_ThrowExceptionToJava(env, "java/io/IOException", + "can't get Available from native Stream"); + } + + return; +} diff --git a/java/webclient/src_share/jni_util.cpp b/java/webclient/src_share/jni_util.cpp index dcf7639ac0f..9a88f6a0f54 100644 --- a/java/webclient/src_share/jni_util.cpp +++ b/java/webclient/src_share/jni_util.cpp @@ -75,6 +75,9 @@ jobject ONE_VALUE; jobject TWO_VALUE; jobject URI_VALUE; jobject HEADERS_VALUE; +jobject METHOD_VALUE; +jobject STATUS_VALUE; +jobject REQUEST_BODY_VALUE; jobject MESSAGE_VALUE; jobject BM_ADD_DATE_VALUE; jobject BM_LAST_MODIFIED_DATE_VALUE; @@ -270,6 +273,21 @@ jboolean util_InitStringConstants() ::util_NewStringUTF(env, "headers")))) { return JNI_FALSE; } + if (nsnull == (STATUS_VALUE = + ::util_NewGlobalRef(env, (jobject) + ::util_NewStringUTF(env, "status")))) { + return JNI_FALSE; + } + if (nsnull == (REQUEST_BODY_VALUE = + ::util_NewGlobalRef(env, (jobject) + ::util_NewStringUTF(env, "requestBody")))) { + return JNI_FALSE; + } + if (nsnull == (METHOD_VALUE = + ::util_NewGlobalRef(env, (jobject) + ::util_NewStringUTF(env, "method")))) { + return JNI_FALSE; + } if (nsnull == (MESSAGE_VALUE = ::util_NewGlobalRef(env, (jobject) ::util_NewStringUTF(env, "message")))) { @@ -351,11 +369,17 @@ jboolean util_StringConstantsAreInitialized() } void util_ThrowExceptionToJava (JNIEnv * env, const char * message) +{ + util_ThrowExceptionToJava(env, "java/lang/RuntimeException", message); +} + +void util_ThrowExceptionToJava (JNIEnv * env, const char * exceptionClass, + const char * message) { if (env->ExceptionOccurred()) { env->ExceptionClear(); } - jclass excCls = env->FindClass("java/lang/RuntimeException"); + jclass excCls = env->FindClass(exceptionClass); if (excCls == 0) { // Unable to find the exception class, give up. if (env->ExceptionOccurred()) diff --git a/java/webclient/src_share/jni_util.h b/java/webclient/src_share/jni_util.h index 3335d93a81c..7cccdd644fa 100644 --- a/java/webclient/src_share/jni_util.h +++ b/java/webclient/src_share/jni_util.h @@ -90,6 +90,9 @@ extern jobject ONE_VALUE; extern jobject TWO_VALUE; extern jobject URI_VALUE; extern jobject HEADERS_VALUE; +extern jobject METHOD_VALUE; +extern jobject STATUS_VALUE; +extern jobject REQUEST_BODY_VALUE; extern jobject MESSAGE_VALUE; extern jobject BM_ADD_DATE_VALUE; extern jobject BM_LAST_MODIFIED_DATE_VALUE; @@ -252,6 +255,8 @@ jboolean util_InitStringConstants(); jboolean util_StringConstantsAreInitialized(); void util_ThrowExceptionToJava (JNIEnv * env, const char * message); +void util_ThrowExceptionToJava (JNIEnv * env, const char *exceptionClass, + const char * message); /** diff --git a/java/webclient/test/automated/src/classes/org/mozilla/webclient/DocumentLoadListenerTest.java b/java/webclient/test/automated/src/classes/org/mozilla/webclient/DocumentLoadListenerTest.java index 54c33eb93c3..7595f9e4471 100644 --- a/java/webclient/test/automated/src/classes/org/mozilla/webclient/DocumentLoadListenerTest.java +++ b/java/webclient/test/automated/src/classes/org/mozilla/webclient/DocumentLoadListenerTest.java @@ -1,5 +1,5 @@ /* - * $Id: DocumentLoadListenerTest.java,v 1.2 2004-10-20 02:50:44 edburns%acm.org Exp $ + * $Id: DocumentLoadListenerTest.java,v 1.3 2005-02-28 17:15:45 edburns%acm.org Exp $ */ /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- @@ -31,12 +31,14 @@ import junit.framework.TestSuite; import java.util.Iterator; import java.util.Map; +import java.util.BitSet; import java.awt.Frame; import java.awt.BorderLayout; import java.io.File; import java.io.FileInputStream; +import java.io.InputStream; // DocumentLoadListenerTest.java @@ -136,6 +138,8 @@ public class DocumentLoadListenerTest extends WebclientTestCase { BrowserControl firstBrowserControl = null; DocumentLoadListener listener = null; Selection selection = null; + final StringBuffer methodToCheck = new StringBuffer(); + final BitSet listenerResult = new BitSet(); firstBrowserControl = BrowserControlFactory.newBrowserControl(); assertNotNull(firstBrowserControl); BrowserControlCanvas canvas = (BrowserControlCanvas) @@ -166,36 +170,66 @@ public class DocumentLoadListenerTest extends WebclientTestCase { public void eventDispatched(WebclientEvent event) { Map map = null; Iterator iter = null; + Object requestMethod; if (event instanceof DocumentLoadEvent) { switch ((int) event.getType()) { case ((int) DocumentLoadEvent.START_URL_LOAD_EVENT_MASK): + // do we have eventData? assertNotNull(event.getEventData()); + // is it a map? assertTrue(event.getEventData() instanceof Map); map = (Map) event.getEventData(); + // does it have a URI entry? assertEquals(url, map.get("URI")); + // does it have a method entry + requestMethod = map.get("method"); + assertNotNull(requestMethod); + // is it the expected value? + assertEquals(methodToCheck.toString(), + requestMethod.toString()); + + // does it have a headers entry? assertNotNull(map.get("headers")); + // is it a map? assertTrue(map.get("headers") instanceof Map); iter = (map = (Map) map.get("headers")).keySet().iterator(); - boolean hadCorrectUserAgentHeader = false; + boolean hadCorrectHostHeader = false; while (iter.hasNext()) { String curName = iter.next().toString(); if (curName.equals("Host")) { if (-1 != map.get(curName).toString().indexOf("localhost")) { - hadCorrectUserAgentHeader = true; + hadCorrectHostHeader = true; } } - System.out.println("\t" + curName + - ": " + - map.get(curName)); } - assertTrue(hadCorrectUserAgentHeader); + // does it have the correct entry? + assertTrue(hadCorrectHostHeader); break; case ((int) DocumentLoadEvent.END_URL_LOAD_EVENT_MASK): + // do we have eventData? assertNotNull(event.getEventData()); + // is it a map? assertTrue(event.getEventData() instanceof Map); map = (Map) event.getEventData(); + // do we have a URI entry? assertEquals(url, map.get("URI")); + + // do we have a method entry + requestMethod = map.get("method"); + assertNotNull(requestMethod); + // is it the expected value + assertEquals(methodToCheck.toString(), + requestMethod.toString()); + + if (requestMethod.equals("GET")) { + // do we have a status entry + Object responseCode = map.get("status"); + assertNotNull(responseCode); + assertEquals("200 OK",responseCode.toString()); + } + + // do we have a headers entry? assertNotNull(map.get("headers")); assertTrue(map.get("headers") instanceof Map); iter = (map = (Map) map.get("headers")).keySet().iterator(); @@ -213,6 +247,49 @@ public class DocumentLoadListenerTest extends WebclientTestCase { } assertTrue(hadCorrectServerHeader); break; + case ((int) DocumentLoadEvent.END_DOCUMENT_LOAD_EVENT_MASK): + // do we have eventData? + assertNotNull(event.getEventData()); + // is it a map? + assertTrue(event.getEventData() instanceof Map); + map = (Map) event.getEventData(); + // do we have a URI entry? + assertEquals(url, map.get("URI")); + + // do we have a method entry + requestMethod = map.get("method"); + assertNotNull(requestMethod); + // is it the expected value + assertEquals(methodToCheck.toString(), + requestMethod.toString()); + + // do we have a status entry + Object responseCode = map.get("status"); + assertNotNull(responseCode); + assertEquals("200 OK",responseCode.toString()); + + /** + if (requestMethod.equals("POST")) { + listenerResult.set(0); + InputStream requestBody = (InputStream) + map.get("requestBody"); + assertNotNull(requestBody); + int avail; + byte bytes[]; + try { + while (0 < (avail = requestBody.available())) { + bytes = new byte[avail]; + requestBody.read(bytes); + System.out.write(bytes); + } + } + catch (java.io.IOException e) { + fail(); + } + } + ***/ + break; + } } DocumentLoadListenerTest.keepWaiting = false; @@ -221,12 +298,29 @@ public class DocumentLoadListenerTest extends WebclientTestCase { Thread.currentThread().sleep(3000); + methodToCheck.replace(0, methodToCheck.length(), "GET"); + System.out.println("++++++++++ Testing GET to " + url); nav.loadURL(url); // keep waiting until the previous load completes while (DocumentLoadListenerTest.keepWaiting) { Thread.currentThread().sleep(1000); } + + Thread.currentThread().sleep(3000); + + /********** + methodToCheck.replace(0, methodToCheck.length(), "POST"); + System.out.println("++++++++++ Testing POST to " + url); + nav.post(url, null, "PostData\r\n", "X-WakaWaka: true\r\n\r\n"); + + // keep waiting until the previous load completes + while (NavigationTest.keepWaiting) { + Thread.currentThread().sleep(1000); + } + assertTrue(listenerResult.get(0)); + **********/ + eventRegistration.removeDocumentLoadListener(listener); frame.setVisible(false);