aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--java/CurlGlue.java134
-rw-r--r--java/CurlWrite.java9
-rw-r--r--java/Makefile33
-rw-r--r--java/javacurl.c157
-rw-r--r--java/test.java27
5 files changed, 360 insertions, 0 deletions
diff --git a/java/CurlGlue.java b/java/CurlGlue.java
new file mode 100644
index 000000000..fe8f186e6
--- /dev/null
+++ b/java/CurlGlue.java
@@ -0,0 +1,134 @@
+/**
+ * The curl class is a JNI wrapper for libcurl. Please bear with me, I'm no
+ * true java dude (yet). Improve what you think is bad and send me the
+ * updates!
+ * daniel@haxx.se
+ *
+ * This is meant as a raw, crude and low-level interface to libcurl. If you
+ * want fancy stuff, build upon this.
+ */
+
+public class CurlGlue
+{
+ // start of imported generated list, make a new list with
+ // define2java.pl on demand
+ public static final int CURLOPT_NOTHING = 0;
+ public static final int CURLOPT_FILE = 10001;
+ public static final int CURLOPT_URL = 10002;
+ public static final int CURLOPT_PORT = 3;
+ public static final int CURLOPT_PROXY = 10004;
+ public static final int CURLOPT_USERPWD = 10005;
+ public static final int CURLOPT_PROXYUSERPWD = 10006;
+ public static final int CURLOPT_RANGE = 10007;
+ public static final int CURLOPT_INFILE = 10009;
+ public static final int CURLOPT_ERRORBUFFER = 10010;
+ public static final int CURLOPT_WRITEFUNCTION = 20011;
+ public static final int CURLOPT_READFUNCTION = 20012;
+ public static final int CURLOPT_TIMEOUT = 13;
+ public static final int CURLOPT_INFILESIZE = 14;
+ public static final int CURLOPT_POSTFIELDS = 10015;
+ public static final int CURLOPT_REFERER = 10016;
+ public static final int CURLOPT_FTPPORT = 10017;
+ public static final int CURLOPT_USERAGENT = 10018;
+ public static final int CURLOPT_LOW_SPEED_LIMIT = 19;
+ public static final int CURLOPT_LOW_SPEED_TIME = 20;
+ public static final int CURLOPT_RESUME_FROM = 21;
+ public static final int CURLOPT_COOKIE = 10022;
+ public static final int CURLOPT_HTTPHEADER = 10023;
+ public static final int CURLOPT_HTTPPOST = 10024;
+ public static final int CURLOPT_SSLCERT = 10025;
+ public static final int CURLOPT_SSLCERTPASSWD = 10026;
+ public static final int CURLOPT_CRLF = 27;
+ public static final int CURLOPT_QUOTE = 10028;
+ public static final int CURLOPT_WRITEHEADER = 10029;
+ public static final int CURLOPT_COOKIEFILE = 10031;
+ public static final int CURLOPT_SSLVERSION = 32;
+ public static final int CURLOPT_TIMECONDITION = 33;
+ public static final int CURLOPT_TIMEVALUE = 34;
+ public static final int CURLOPT_HTTPREQUEST = 10035;
+ public static final int CURLOPT_CUSTOMREQUEST = 10036;
+ public static final int CURLOPT_STDERR = 10037;
+ public static final int CURLOPT_POSTQUOTE = 10039;
+ public static final int CURLOPT_WRITEINFO = 10040;
+ public static final int CURLOPT_VERBOSE = 41;
+ public static final int CURLOPT_HEADER = 42;
+ public static final int CURLOPT_NOPROGRESS = 43;
+ public static final int CURLOPT_NOBODY = 44;
+ public static final int CURLOPT_FAILONERROR = 45;
+ public static final int CURLOPT_UPLOAD = 46;
+ public static final int CURLOPT_POST = 47;
+ public static final int CURLOPT_FTPLISTONLY = 48;
+ public static final int CURLOPT_FTPAPPEND = 50;
+ public static final int CURLOPT_NETRC = 51;
+ public static final int CURLOPT_FOLLOWLOCATION = 52;
+ public static final int CURLOPT_FTPASCII = 53;
+ public static final int CURLOPT_TRANSFERTEXT = 53;
+ public static final int CURLOPT_PUT = 54;
+ public static final int CURLOPT_MUTE = 55;
+ public static final int CURLOPT_PROGRESSFUNCTION = 20056;
+ public static final int CURLOPT_PROGRESSDATA = 10057;
+ public static final int CURLOPT_AUTOREFERER = 58;
+ public static final int CURLOPT_PROXYPORT = 59;
+ public static final int CURLOPT_POSTFIELDSIZE = 60;
+ public static final int CURLOPT_HTTPPROXYTUNNEL = 61;
+ public static final int CURLOPT_INTERFACE = 10062;
+ public static final int CURLOPT_KRB4LEVEL = 10063;
+ public static final int CURLOPT_SSL_VERIFYPEER = 64;
+ public static final int CURLOPT_CAINFO = 10065;
+ public static final int CURLOPT_PASSWDFUNCTION = 20066;
+ public static final int CURLOPT_PASSWDDATA = 10067;
+ public static final int CURLOPT_MAXREDIRS = 68;
+ public static final int CURLOPT_FILETIME = 10069;
+ public static final int CURLOPT_TELNETOPTIONS = 10070;
+ public static final int CURLOPT_MAXCONNECTS = 71;
+ public static final int CURLOPT_CLOSEPOLICY = 72;
+ public static final int CURLOPT_CLOSEFUNCTION = 20073;
+ public static final int CURLOPT_FRESH_CONNECT = 74;
+ public static final int CURLOPT_FORBID_REUSE = 75;
+ public static final int CURLOPT_RANDOM_FILE = 10076;
+ public static final int CURLOPT_EGDSOCKET = 10077;
+ public static final int CURLOPT_CONNECTTIMEOUT = 78;
+ public static final int CURLOPT_HEADERFUNCTION = 20079;
+ // end of generated list
+
+ public CurlGlue() {
+ javacurl_handle = jni_init();
+ }
+
+ public void finalize() {
+ jni_cleanup(javacurl_handle);
+ }
+
+ private int javacurl_handle;
+
+ /* constructor and destructor for the libcurl handle */
+ private native int jni_init();
+ private native void jni_cleanup(int javacurl_handle);
+ private native synchronized int jni_perform(int javacurl_handle);
+
+ // Instead of varargs, we have different functions for each
+ // kind of type setopt() can take
+ private native int jni_setopt(int libcurl, int option, String value);
+ private native int jni_setopt(int libcurl, int option, int value);
+ private native int jni_setopt(int libcurl, int option, CurlWrite value);
+
+ public native int getinfo();
+
+ public int perform() {
+ return jni_perform(javacurl_handle);
+ }
+ public int setopt(int option, int value) {
+ return jni_setopt(javacurl_handle, option, value);
+ }
+ public int setopt(int option, String value) {
+ return jni_setopt(javacurl_handle, option, value);
+ }
+ public int setopt(int option, CurlWrite value) {
+ return jni_setopt(javacurl_handle, option, value);
+ }
+
+ static {
+ System.loadLibrary("javacurl");
+ }
+
+}
diff --git a/java/CurlWrite.java b/java/CurlWrite.java
new file mode 100644
index 000000000..37c8484c0
--- /dev/null
+++ b/java/CurlWrite.java
@@ -0,0 +1,9 @@
+public interface CurlWrite
+{
+ /**
+ * handleString gets called by libcurl on each chunk of data
+ * we receive from the remote server
+ */
+ public int handleString(byte s[]);
+}
+
diff --git a/java/Makefile b/java/Makefile
new file mode 100644
index 000000000..e05ea6004
--- /dev/null
+++ b/java/Makefile
@@ -0,0 +1,33 @@
+
+TARGET = libjavacurl.so
+
+OBJS = javacurl.o
+
+CC = gcc
+CFLAGS = -c
+CPPFLAGS = -I/usr/j2se/include -I/usr/local/include -I/usr/j2se/include/solaris
+LDFLAGS = -lcurl -ldl -L/usr/local/ssl/lib -lssl -lcrypto
+
+all: CurlGlue.h CurlGlue.class javacurl.o $(TARGET) test.class
+
+test:
+ java test
+
+javacurl.o: javacurl.c CurlGlue.h
+ $(CC) $(CPPFLAGS) $(CFLAGS) $<
+
+CurlGlue.h: CurlGlue.java CurlGlue.class
+ javah CurlGlue
+ touch CurlGlue.h
+
+test.class: CurlGlue.class javacurl.o
+ javac test.java
+
+CurlGlue.class: CurlGlue.java
+ javac $<
+
+$(TARGET): $(OBJS)
+ $(CC) -G -o $(TARGET) $(LDFLAGS) $(OBJS)
+
+clean:
+ rm -f javacurl.o CurlGlue.h CurlGlue.class
diff --git a/java/javacurl.c b/java/javacurl.c
new file mode 100644
index 000000000..2b93bc677
--- /dev/null
+++ b/java/javacurl.c
@@ -0,0 +1,157 @@
+
+#include <curl/curl.h> /* libcurl header */
+#include "CurlGlue.h" /* the JNI-generated glue header file */
+
+/*
+ * This is a private struct allocated for every 'CurlGlue' object.
+ */
+struct javacurl {
+ void *libcurl;
+ void *whatever;
+ struct writecallback {
+ jmethodID mid;
+ JNIEnv *java;
+ jclass cls;
+ jobject obj;
+ } write;
+};
+
+JNIEXPORT jint JNICALL Java_CurlGlue_jni_1init(JNIEnv *java,
+ jobject myself)
+{
+ void *libhandle;
+ struct javacurl *jcurl=NULL;
+
+ libhandle = curl_easy_init();
+
+ if(libhandle) {
+ jcurl=(struct javacurl *)malloc(sizeof(struct javacurl));
+ if(jcurl) {
+ memset(jcurl, 0, sizeof(struct javacurl));
+ jcurl->libcurl = libhandle;
+
+ }
+ else {
+ curl_easy_cleanup(libhandle);
+ return (jint)0;
+ }
+ }
+
+ return (jint) jcurl; /* nasty typecast */
+}
+
+JNIEXPORT void JNICALL Java_CurlGlue_jni_1cleanup(JNIEnv *java,
+ jobject myself,
+ jint jcurl)
+{
+ void *handle=(void *)((struct javacurl*)jcurl)->libcurl;
+
+ curl_easy_cleanup(handle); /* cleanup libcurl stuff */
+
+ free((void *)jcurl); /* free the struct too */
+}
+
+/*
+ * setopt() int + string
+ */
+JNIEXPORT jint JNICALL Java_CurlGlue_jni_1setopt__IILjava_lang_String_2
+ (JNIEnv *java, jobject myself, jint jcurl, jint option, jstring value)
+{
+ /* get the actual string C-style */
+ const char *str = (*java)->GetStringUTFChars(java, value, 0);
+
+ void *handle = (void *)((struct javacurl*)jcurl)->libcurl;
+
+ puts("setopt int + string");
+
+ return (jint)curl_easy_setopt(handle, (CURLoption)option, str);
+
+}
+
+/*
+ * setopt() int + int
+ */
+JNIEXPORT jint JNICALL Java_CurlGlue_jni_1setopt__III
+ (JNIEnv *java, jobject myself, jint jcurl, jint option, jint value)
+{
+ void *handle = (void *)((struct javacurl*)jcurl)->libcurl;
+
+ puts("setopt int + int");
+
+ return (jint)curl_easy_setopt(handle, (CURLoption)option, value);
+}
+
+static int javacurl_write_callback(void *ptr,
+ size_t size,
+ size_t nmemb,
+ FILE *stream)
+{
+ struct javacurl *curl = (struct javacurl *)stream;
+ size_t realsize = size * nmemb;
+ JNIEnv *java = curl->write.java;
+ jbyteArray jb;
+ int ret;
+
+ jb=(*java)->NewByteArray(java, realsize);
+ (*java)->SetByteArrayRegion(java, jb, 0,
+ realsize, (jbyte *)ptr);
+
+ ret = (*java)->CallIntMethod(java,
+ curl->write.obj,
+ curl->write.mid,
+ jb);
+
+ return realsize;
+}
+
+/*
+ * setopt() int + object
+ */
+
+JNIEXPORT jint JNICALL Java_CurlGlue_jni_1setopt__IILCurlWrite_2
+ (JNIEnv *java, jobject myself, jint jcurl, jint option, jobject value)
+{
+ jclass cls = (*java)->GetObjectClass(java, value);
+ jmethodID mid;
+ struct javacurl *curl = (struct javacurl *)jcurl;
+
+ printf("setopt int + object, option = %d cls= %p\n", option, cls);
+
+ switch(option) {
+ case CURLOPT_WRITEFUNCTION:
+ /* this is the write callback */
+ mid = (*java)->GetMethodID(java, cls, "handleString",
+ "([B)I");
+ if(!mid) {
+ /* no callback method found */
+ puts("no callback method found");
+ return 0;
+ }
+ curl->write.mid = mid;
+ curl->write.java = java;
+ curl->write.cls = cls;
+ curl->write.obj = value;
+
+ puts("setopt write callback and write file pointer");
+
+ curl_easy_setopt(curl->libcurl, CURLOPT_WRITEFUNCTION,
+ javacurl_write_callback);
+ curl_easy_setopt(curl->libcurl, CURLOPT_FILE,
+ curl);
+ break;
+ }
+ return 0;
+}
+
+JNIEXPORT jint JNICALL Java_CurlGlue_getinfo
+ (JNIEnv *java, jobject value)
+{
+ return 0;
+}
+
+JNIEXPORT jint JNICALL Java_CurlGlue_jni_1perform
+ (JNIEnv *java, jobject myself, jint jcurl)
+{
+ void *handle=(void *)((struct javacurl*)jcurl)->libcurl;
+ return (jint)curl_easy_perform(handle);
+}
diff --git a/java/test.java b/java/test.java
new file mode 100644
index 000000000..33da88030
--- /dev/null
+++ b/java/test.java
@@ -0,0 +1,27 @@
+import CurlGlue;
+import CurlWrite;
+
+class test implements CurlWrite {
+ public int handleString(byte s[])
+ {
+ /* output everything */
+ System.out.println("IIIIIIIIIII -------------- OOOOOOOOOOOOOOOOOOO");
+ try {
+ System.out.write(s);
+ }
+ catch (java.io.IOException moo) {
+ // nothing
+ }
+ return 0;
+ }
+
+ public static void main(String[] args)
+ {
+ CurlGlue cg = new CurlGlue();
+ test cw = new test();
+ cg.setopt(CurlGlue.CURLOPT_URL, "http://www.contactor.se/");
+ cg.setopt(CurlGlue.CURLOPT_WRITEFUNCTION, cw);
+ cg.perform();
+ }
+}
+