couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dav...@apache.org
Subject svn commit: r1166525 - in /couchdb/branches/1.1.x: ./ share/server/ share/www/script/ src/couchdb/priv/ src/couchdb/priv/couch_js/ test/javascript/
Date Thu, 08 Sep 2011 05:00:10 GMT
Author: davisp
Date: Thu Sep  8 05:00:10 2011
New Revision: 1166525

URL: http://svn.apache.org/viewvc?rev=1166525&view=rev
Log:
Fix CouchJS compatibility with older SpiderMonkey.

This is a backport of the work to make CouchJS build against all of the
major versions of SpiderMonkey. Thanks to Randall Leeds and Chris
Coulson for the original patches.

Backport based on r1137464 and r1164346
Fixes COUCHDB-1078
Fixes COUCHDB-1260


Modified:
    couchdb/branches/1.1.x/configure.ac
    couchdb/branches/1.1.x/share/server/mimeparse.js
    couchdb/branches/1.1.x/share/www/script/couch_test_runner.js
    couchdb/branches/1.1.x/src/couchdb/priv/Makefile.am
    couchdb/branches/1.1.x/src/couchdb/priv/couch_js/http.c
    couchdb/branches/1.1.x/src/couchdb/priv/couch_js/http.h
    couchdb/branches/1.1.x/src/couchdb/priv/couch_js/main.c
    couchdb/branches/1.1.x/src/couchdb/priv/couch_js/utf8.c
    couchdb/branches/1.1.x/test/javascript/run.tpl

Modified: couchdb/branches/1.1.x/configure.ac
URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/configure.ac?rev=1166525&r1=1166524&r2=1166525&view=diff
==============================================================================
--- couchdb/branches/1.1.x/configure.ac (original)
+++ couchdb/branches/1.1.x/configure.ac Thu Sep  8 05:00:10 2011
@@ -108,13 +108,15 @@ esac
 
 AM_CONDITIONAL([WINDOWS], [test x$IS_WINDOWS = xTRUE])
 
-AC_CHECK_LIB([mozjs], [JS_NewContext], [JS_LIB_BASE=mozjs], [
-    AC_CHECK_LIB([js], [JS_NewContext], [JS_LIB_BASE=js], [
-        AC_CHECK_LIB([js3250], [JS_NewContext], [JS_LIB_BASE=js3250], [
-            AC_CHECK_LIB([js32], [JS_NewContext], [JS_LIB_BASE=js32], [
-                AC_MSG_ERROR([Could not find the js library.
+AC_CHECK_LIB([mozjs185], [JS_NewContext], [JS_LIB_BASE=mozjs185], [
+    AC_CHECK_LIB([mozjs185-1.0], [JS_NewContext], [JS_LIB_BASE=mozjs185-1.0], [
+        AC_CHECK_LIB([mozjs], [JS_NewContext], [JS_LIB_BASE=mozjs], [
+            AC_CHECK_LIB([js], [JS_NewContext], [JS_LIB_BASE=js], [
+                AC_CHECK_LIB([js3250], [JS_NewContext], [JS_LIB_BASE=js3250], [
+                    AC_CHECK_LIB([js32], [JS_NewContext], [JS_LIB_BASE=js32], [
+                        AC_MSG_ERROR([Could not find the js library.
 
-Is the Mozilla SpiderMonkey library installed?])])])])])
+Is the Mozilla SpiderMonkey library installed?])])])])])])])
 
 AC_SUBST(JS_LIB_BASE)
 
@@ -177,16 +179,19 @@ Are the Mozilla SpiderMonkey headers ins
 AC_SUBST(JSLIB)
 
 AC_LANG_PUSH(C)
-OLD_CFLAGS="$CFLAGS"
-CFLAGS="-Werror-implicit-function-declaration"
-AC_COMPILE_IFELSE(
-    [AC_LANG_PROGRAM(
-        [[#include <jsapi.h>]],
-        [[JS_SetOperationCallback(0, 0);]]
-    )],
-    AC_DEFINE([USE_JS_SETOPCB], [], [Use new JS_SetOperationCallback])
-)
-CFLAGS="$OLD_CFLAGS"
+
+AC_CHECK_LIB([$JS_LIB_BASE], [JS_NewCompartmentAndGlobalObject],
+    AC_DEFINE([SM185], [1],
+        [Use SpiderMonkey 1.8.5]))
+
+AC_CHECK_LIB([$JS_LIB_BASE], [JS_ThrowStopIteration],
+    AC_DEFINE([SM180], [1],
+        [Use SpiderMonkey 1.8.0]))
+
+AC_CHECK_LIB([$JS_LIB_BASE], [JS_GetStringCharsAndLength],
+    AC_DEFINE([HAVE_JS_GET_STRING_CHARS_AND_LENGTH], [1],
+        [Use newer JS_GetCharsAndLength function.]))
+
 AC_LANG_POP(C)
 
 AC_ARG_WITH([win32-icu-binaries], [AC_HELP_STRING([--with-win32-icu-binaries=PATH],
@@ -228,10 +233,10 @@ case "$(uname -s)" in
     CPPFLAGS="-D_XOPEN_SOURCE $CPPFLAGS"
     ;;
   FreeBSD)
-    LIBS="$LIBS -lcrypt"
+    LIBS="$LIBS -lm -lcrypt"
     ;;
   OpenBSD)
-    LIBS="$LIBS -lcrypto"
+    LIBS="$LIBS -lm -lcrypto"
   ;;
 esac
 

Modified: couchdb/branches/1.1.x/share/server/mimeparse.js
URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/share/server/mimeparse.js?rev=1166525&r1=1166524&r2=1166525&view=diff
==============================================================================
--- couchdb/branches/1.1.x/share/server/mimeparse.js (original)
+++ couchdb/branches/1.1.x/share/server/mimeparse.js Thu Sep  8 05:00:10 2011
@@ -97,7 +97,7 @@ var Mimeparse = (function() {
         if ((type == targetType || type == "*" || targetType == "*") &&
           (subtype == targetSubtype || subtype == "*" || targetSubtype == "*")) {
           var matchCount = 0;
-          for (param in targetParams) {
+          for (var param in targetParams) {
             if (param != 'q' && params[param] && params[param] == targetParams[param])
{
               matchCount += 1;
             }

Modified: couchdb/branches/1.1.x/share/www/script/couch_test_runner.js
URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/share/www/script/couch_test_runner.js?rev=1166525&r1=1166524&r2=1166525&view=diff
==============================================================================
--- couchdb/branches/1.1.x/share/www/script/couch_test_runner.js (original)
+++ couchdb/branches/1.1.x/share/www/script/couch_test_runner.js Thu Sep  8 05:00:10 2011
@@ -414,9 +414,22 @@ function waitForSuccess(fun, tag) {
 
 function waitForRestart() {
   var waiting = true;
-  while (waiting) {
+  // Wait for the server to go down but don't
+  // wait too long because we might miss the
+  // unavailable period.
+  var count = 25;
+  while (waiting && count > 0) {
+    count--;
     try {
       CouchDB.request("GET", "/");
+    } catch(e) {
+      waiting = false;
+    }
+  }
+  // Wait for it to come back up
+  waiting = true;
+  while (waiting) {
+    try {
       CouchDB.request("GET", "/");
       waiting = false;
     } catch(e) {

Modified: couchdb/branches/1.1.x/src/couchdb/priv/Makefile.am
URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/src/couchdb/priv/Makefile.am?rev=1166525&r1=1166524&r2=1166525&view=diff
==============================================================================
--- couchdb/branches/1.1.x/src/couchdb/priv/Makefile.am (original)
+++ couchdb/branches/1.1.x/src/couchdb/priv/Makefile.am Thu Sep  8 05:00:10 2011
@@ -16,7 +16,10 @@ couchprivlibdir = $(couchlibdir)/priv/li
 
 EXTRA_DIST = \
 	spawnkillable/couchspawnkillable.sh \
-	stat_descriptions.cfg.in
+	stat_descriptions.cfg.in \
+	couch_js/sm170.c \
+	couch_js/sm180.c \
+	couch_js/sm185.c
 
 CLEANFILES = stat_descriptions.cfg
 
@@ -42,12 +45,14 @@ COUCHJS_SRCS = \
 	couch_js/http.h \
 	couch_js/main.c \
 	couch_js/utf8.c \
-	couch_js/utf8.h
+	couch_js/utf8.h \
+	couch_js/util.h \
+	couch_js/util.c
 
 locallibbin_PROGRAMS = couchjs
 couchjs_SOURCES = $(COUCHJS_SRCS)
 couchjs_LDFLAGS = $(CURL_LDFLAGS)
-couchjs_CFLAGS = -D_BSD_SOURCE $(CURL_CFLAGS)
+couchjs_CFLAGS = -g -Wall -Werror -D_BSD_SOURCE $(CURL_CFLAGS)
 couchjs_LDADD = $(CURL_LDFLAGS) @JSLIB@
 
 couchpriv_DATA = stat_descriptions.cfg

Modified: couchdb/branches/1.1.x/src/couchdb/priv/couch_js/http.c
URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/src/couchdb/priv/couch_js/http.c?rev=1166525&r1=1166524&r2=1166525&view=diff
==============================================================================
--- couchdb/branches/1.1.x/src/couchdb/priv/couch_js/http.c (original)
+++ couchdb/branches/1.1.x/src/couchdb/priv/couch_js/http.c Thu Sep  8 05:00:10 2011
@@ -14,19 +14,31 @@
 #include <stdlib.h>
 #include <string.h>
 #include <jsapi.h>
+#include "config.h"
+#include "utf8.h"
+
+
 #include <curl/curl.h>
 
-#include "utf8.h"
 
-#ifdef XP_WIN
+void
+http_check_enabled()
+{
+    return;
+}
+
+
 // Map some of the string function names to things which exist on Windows
+#ifdef XP_WIN
 #define strcasecmp _strcmpi
 #define strncasecmp _strnicmp
 #define snprintf _snprintf
 #endif
 
+
 typedef struct curl_slist CurlHeaders;
 
+
 typedef struct {
     int             method;
     char*           url;
@@ -34,8 +46,10 @@ typedef struct {
     jsint           last_status;
 } HTTPData;
 
+
 char* METHODS[] = {"GET", "HEAD", "POST", "PUT", "DELETE", "COPY", NULL};
 
+
 #define GET     0
 #define HEAD    1
 #define POST    2
@@ -43,14 +57,17 @@ char* METHODS[] = {"GET", "HEAD", "POST"
 #define DELETE  4
 #define COPY    5
 
+
 static JSBool
 go(JSContext* cx, JSObject* obj, HTTPData* http, char* body, size_t blen);
 
+
 static JSString*
 str_from_binary(JSContext* cx, char* data, size_t length);
 
-static JSBool
-constructor(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
+
+JSBool
+http_ctor(JSContext* cx, JSObject* req)
 {
     HTTPData* http = NULL;
     JSBool ret = JS_FALSE;
@@ -67,12 +84,12 @@ constructor(JSContext* cx, JSObject* obj
     http->req_headers = NULL;
     http->last_status = -1;
 
-    if(!JS_SetPrivate(cx, obj, http))
+    if(!JS_SetPrivate(cx, req, http))
     {
         JS_ReportError(cx, "Failed to set private CouchHTTP data.");
         goto error;
     }
-    
+
     ret = JS_TRUE;
     goto success;
 
@@ -83,90 +100,76 @@ success:
     return ret;
 }
 
-static void
-destructor(JSContext* cx, JSObject* obj)
+
+void
+http_dtor(JSContext* cx, JSObject* obj)
 {
     HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj);
-    if(!http)
-    {
-        fprintf(stderr, "Unable to destroy invalid CouchHTTP instance.\n");
-    }
-    else
-    {
+    if(http) { 
         if(http->url) free(http->url);
         if(http->req_headers) curl_slist_free_all(http->req_headers);
         free(http);
     }
 }
 
-static JSBool
-open(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
-{    
-    HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj);
+
+JSBool
+http_open(JSContext* cx, JSObject* req, jsval mth, jsval url, jsval snc)
+{
+    HTTPData* http = (HTTPData*) JS_GetPrivate(cx, req);
     char* method = NULL;
-    char* url = NULL;
-    JSBool ret = JS_FALSE;
     int methid;
+    JSBool ret = JS_FALSE;
 
-    if(!http)
-    {
+    if(!http) {
         JS_ReportError(cx, "Invalid CouchHTTP instance.");
         goto done;
     }
 
-    if(argv[0] == JSVAL_VOID)
-    {
+    if(mth == JSVAL_VOID) {
         JS_ReportError(cx, "You must specify a method.");
         goto done;
     }
 
-    method = enc_string(cx, argv[0], NULL);
-    if(!method)
-    {
+    method = enc_string(cx, mth, NULL);
+    if(!method) {
         JS_ReportError(cx, "Failed to encode method.");
         goto done;
     }
     
-    for(methid = 0; METHODS[methid] != NULL; methid++)
-    {
+    for(methid = 0; METHODS[methid] != NULL; methid++) {
         if(strcasecmp(METHODS[methid], method) == 0) break;
     }
     
-    if(methid > COPY)
-    {
+    if(methid > COPY) {
         JS_ReportError(cx, "Invalid method specified.");
         goto done;
     }
 
     http->method = methid;
 
-    if(argv[1] == JSVAL_VOID)
-    {
+    if(url == JSVAL_VOID) {
         JS_ReportError(cx, "You must specify a URL.");
         goto done;
     }
 
-    if(http->url)
-    {
+    if(http->url != NULL) {
         free(http->url);
         http->url = NULL;
     }
 
-    http->url = enc_string(cx, argv[1], NULL);
-    if(!http->url)
-    {
+    http->url = enc_string(cx, url, NULL);
+    if(http->url == NULL) {
         JS_ReportError(cx, "Failed to encode URL.");
         goto done;
     }
     
-    if(argv[2] != JSVAL_VOID && argv[2] != JSVAL_FALSE)
-    {
-        JS_ReportError(cx, "Synchronous flag must be false if specified.");
+    if(snc != JSVAL_FALSE) {
+        JS_ReportError(cx, "Synchronous flag must be false.");
         goto done;
     }
     
-    if(http->req_headers)
-    {
+    if(http->req_headers) {
         curl_slist_free_all(http->req_headers);
         http->req_headers = NULL;
     }
@@ -181,42 +184,42 @@ done:
     return ret;
 }
 
-static JSBool
-setheader(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
-{    
-    HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj);
+
+JSBool
+http_set_hdr(JSContext* cx, JSObject* req, jsval name, jsval val)
+{
+    HTTPData* http = (HTTPData*) JS_GetPrivate(cx, req);
     char* keystr = NULL;
     char* valstr = NULL;
     char* hdrbuf = NULL;
     size_t hdrlen = -1;
     JSBool ret = JS_FALSE;
 
-    if(!http)
-    {
+    if(!http) {
         JS_ReportError(cx, "Invalid CouchHTTP instance.");
         goto done;
     }
 
-    if(argv[0] == JSVAL_VOID)
+    if(name == JSVAL_VOID)
     {
         JS_ReportError(cx, "You must speciy a header name.");
         goto done;
     }
 
-    keystr = enc_string(cx, argv[0], NULL);
+    keystr = enc_string(cx, name, NULL);
     if(!keystr)
     {
         JS_ReportError(cx, "Failed to encode header name.");
         goto done;
     }
     
-    if(argv[1] == JSVAL_VOID)
+    if(val == JSVAL_VOID)
     {
         JS_ReportError(cx, "You must specify a header value.");
         goto done;
     }
     
-    valstr = enc_string(cx, argv[1], NULL);
+    valstr = enc_string(cx, val, NULL);
     if(!valstr)
     {
         JS_ReportError(cx, "Failed to encode header value.");
@@ -225,8 +228,7 @@ setheader(JSContext* cx, JSObject* obj, 
     
     hdrlen = strlen(keystr) + strlen(valstr) + 3;
     hdrbuf = (char*) malloc(hdrlen * sizeof(char));
-    if(!hdrbuf)
-    {
+    if(!hdrbuf) {
         JS_ReportError(cx, "Failed to allocate header buffer.");
         goto done;
     }
@@ -240,121 +242,50 @@ done:
     if(keystr) free(keystr);
     if(valstr) free(valstr);
     if(hdrbuf) free(hdrbuf);
-
     return ret;
 }
 
-static JSBool
-sendreq(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
+JSBool
+http_send(JSContext* cx, JSObject* req, jsval body)
 {
-    HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj);
-    char* body = NULL;
+    HTTPData* http = (HTTPData*) JS_GetPrivate(cx, req);
+    char* bodystr = NULL;
     size_t bodylen = 0;
     JSBool ret = JS_FALSE;
     
-    if(!http)
-    {
+    if(!http) {
         JS_ReportError(cx, "Invalid CouchHTTP instance.");
         goto done;
     }
 
-    if(argv[0] != JSVAL_VOID && argv[0] != JS_GetEmptyStringValue(cx))
-    {
-        body = enc_string(cx, argv[0], &bodylen);
-        if(!body)
-        {
+    if(body != JSVAL_VOID && body != JS_GetEmptyStringValue(cx)) {
+        bodystr = enc_string(cx, body, &bodylen);
+        if(!bodystr) {
             JS_ReportError(cx, "Failed to encode body.");
             goto done;
         }
     }
 
-    ret = go(cx, obj, http, body, bodylen);
+    ret = go(cx, req, http, bodystr, bodylen);
 
 done:
-    if(body) free(body);
+    if(bodystr) free(bodystr);
     return ret;
 }
 
-static JSBool
-status(JSContext* cx, JSObject* obj, jsval idval, jsval* vp)
+int
+http_status(JSContext* cx, JSObject* req)
 {
-    HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj);
+    HTTPData* http = (HTTPData*) JS_GetPrivate(cx, req);
     
-    if(!http)
-    {
+    if(!http) {
         JS_ReportError(cx, "Invalid CouchHTTP instance.");
         return JS_FALSE;
     }
-    
-    if(INT_FITS_IN_JSVAL(http->last_status))
-    {
-        *vp = INT_TO_JSVAL(http->last_status);
-        return JS_TRUE;
-    }
-    else
-    {
-        JS_ReportError(cx, "INTERNAL: Invalid last_status");
-        return JS_FALSE;
-    }
-}
-
-JSClass CouchHTTPClass = {
-    "CouchHTTP",
-    JSCLASS_HAS_PRIVATE
-        | JSCLASS_CONSTRUCT_PROTOTYPE
-        | JSCLASS_HAS_RESERVED_SLOTS(2),
-    JS_PropertyStub,
-    JS_PropertyStub,
-    JS_PropertyStub,
-    JS_PropertyStub,
-    JS_EnumerateStub,
-    JS_ResolveStub,
-    JS_ConvertStub,
-    destructor,
-    JSCLASS_NO_OPTIONAL_MEMBERS
-};
-
-JSPropertySpec CouchHTTPProperties[] = {
-    {"status", 0, JSPROP_READONLY, status, NULL},
-    {0, 0, 0, 0, 0}
-};
-
-JSFunctionSpec CouchHTTPFunctions[] = {
-    {"_open", open, 3, 0, 0},
-    {"_setRequestHeader", setheader, 2, 0, 0},
-    {"_send", sendreq, 1, 0, 0},
-    {0, 0, 0, 0, 0}
-};
-
-JSObject*
-install_http(JSContext* cx, JSObject* glbl)
-{
-    JSObject* klass = NULL;
-    HTTPData* http = NULL;
-
-    klass = JS_InitClass(
-        cx,
-        glbl,
-        NULL,
-        &CouchHTTPClass,
-        constructor,
-        0,
-        CouchHTTPProperties,
-        CouchHTTPFunctions,
-        NULL,
-        NULL
-    );
 
-    if(!klass)
-    {
-        fprintf(stderr, "Failed to initialize CouchHTTP class.\n");
-        return NULL;
-    }
-    
-    return klass;
+    return http->last_status;
 }
 
-
 // Curl Helpers
 
 typedef struct {
@@ -364,6 +295,7 @@ typedef struct {
     char*       sendbuf;
     size_t      sendlen;
     size_t      sent;
+    int         sent_once;
     char*       recvbuf;
     size_t      recvlen;
     size_t      read;
@@ -395,13 +327,13 @@ go(JSContext* cx, JSObject* obj, HTTPDat
     state.sendbuf = body;
     state.sendlen = bodylen;
     state.sent = 0;
+    state.sent_once = 0;
 
     state.recvbuf = NULL;
     state.recvlen = 0;
     state.read = 0;
 
-    if(HTTP_HANDLE == NULL)
-    {
+    if(HTTP_HANDLE == NULL) {
         HTTP_HANDLE = curl_easy_init();
         curl_easy_setopt(HTTP_HANDLE, CURLOPT_READFUNCTION, send_body);
         curl_easy_setopt(HTTP_HANDLE, CURLOPT_SEEKFUNCTION,
@@ -416,14 +348,12 @@ go(JSContext* cx, JSObject* obj, HTTPDat
                                             "CouchHTTP Client - Relax");
     }
     
-    if(!HTTP_HANDLE)
-    {
+    if(!HTTP_HANDLE) {
         JS_ReportError(cx, "Failed to initialize cURL handle.");
         goto done;
     }
 
-    if(http->method < 0 || http->method > COPY)
-    {
+    if(http->method < 0 || http->method > COPY) {
         JS_ReportError(cx, "INTERNAL: Unknown method.");
         goto done;
     }
@@ -433,27 +363,21 @@ go(JSContext* cx, JSObject* obj, HTTPDat
     curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 1);
     curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 0);
     
-    if(http->method == HEAD)
-    {
+    if(http->method == HEAD) {
         curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOBODY, 1);
         curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 0);
-    }
-    else if(http->method == POST || http->method == PUT)
-    {
+    } else if(http->method == POST || http->method == PUT) {
         curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 1);
         curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 0);
     }
     
-    if(body && bodylen)
-    {
+    if(body && bodylen) {
         curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, bodylen);        
-    }
-    else
-    {
+    } else {
         curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, 0);
     }
 
-    //curl_easy_setopt(HTTP_HANDLE, CURLOPT_VERBOSE, 1);
+    // curl_easy_setopt(HTTP_HANDLE, CURLOPT_VERBOSE, 1);
 
     curl_easy_setopt(HTTP_HANDLE, CURLOPT_URL, http->url);
     curl_easy_setopt(HTTP_HANDLE, CURLOPT_HTTPHEADER, http->req_headers);
@@ -462,39 +386,32 @@ go(JSContext* cx, JSObject* obj, HTTPDat
     curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEHEADER, &state);
     curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEDATA, &state);
 
-    if(curl_easy_perform(HTTP_HANDLE) != 0)
-    {
+    if(curl_easy_perform(HTTP_HANDLE) != 0) {
         JS_ReportError(cx, "Failed to execute HTTP request: %s", ERRBUF);
         goto done;
     }
     
-    if(!state.resp_headers)
-    {
+    if(!state.resp_headers) {
         JS_ReportError(cx, "Failed to recieve HTTP headers.");
         goto done;
     }
 
     tmp = OBJECT_TO_JSVAL(state.resp_headers);
     if(!JS_DefineProperty(
-        cx,
-        obj,
+        cx, obj,
         "_headers",
         tmp,
-        NULL,
-        NULL,
+        NULL, NULL,
         JSPROP_READONLY
-    ))
-    {
+    )) {
         JS_ReportError(cx, "INTERNAL: Failed to set response headers.");
         goto done;
     }
     
-    if(state.recvbuf) // Is good enough?
-    {
+    if(state.recvbuf) {
         state.recvbuf[state.read] = '\0';
         jsbody = dec_string(cx, state.recvbuf, state.read+1);
-        if(!jsbody)
-        {
+        if(!jsbody) {
             // If we can't decode the body as UTF-8 we forcefully
             // convert it to a string by just forcing each byte
             // to a jschar.
@@ -507,22 +424,17 @@ go(JSContext* cx, JSObject* obj, HTTPDat
             }
         }
         tmp = STRING_TO_JSVAL(jsbody);
-    }
-    else
-    {
+    } else {
         tmp = JS_GetEmptyStringValue(cx);
     }
     
     if(!JS_DefineProperty(
-        cx,
-        obj,
+        cx, obj,
         "responseText",
         tmp,
-        NULL,
-        NULL,
+        NULL, NULL,
         JSPROP_READONLY
-    ))
-    {
+    )) {
         JS_ReportError(cx, "INTERNAL: Failed to set responseText.");
         goto done;
     }
@@ -540,15 +452,20 @@ send_body(void *ptr, size_t size, size_t
     CurlState* state = (CurlState*) data;
     size_t length = size * nmem;
     size_t towrite = state->sendlen - state->sent;
-    if(towrite == 0)
-    {
+
+    // Assume this is cURL trying to resend a request that
+    // failed.
+    if(towrite == 0 && state->sent_once == 0) {
+        state->sent_once = 1;
         return 0;
+    } else if(towrite == 0) {
+        state->sent = 0;
+        state->sent_once = 0;
+        towrite = state->sendlen;
     }
 
     if(length < towrite) towrite = length;
 
-    //fprintf(stderr, "%lu %lu %lu %lu\n", state->bodyused, state->bodyread, length,
towrite);
-
     memcpy(ptr, state->sendbuf + state->sent, towrite);
     state->sent += towrite;
 
@@ -572,15 +489,12 @@ recv_header(void *ptr, size_t size, size
     char code[4];
     char* header = (char*) ptr;
     size_t length = size * nmem;
-    size_t index = 0;
     JSString* hdr = NULL;
     jsuint hdrlen;
     jsval hdrval;
     
-    if(length > 7 && strncasecmp(header, "HTTP/1.", 7) == 0)
-    {
-        if(length < 12)
-        {
+    if(length > 7 && strncasecmp(header, "HTTP/1.", 7) == 0) {
+        if(length < 12) {
             return CURLE_WRITE_ERROR;
         }
 
@@ -589,8 +503,7 @@ recv_header(void *ptr, size_t size, size
         state->http->last_status = atoi(code);
 
         state->resp_headers = JS_NewArrayObject(state->cx, 0, NULL);
-        if(!state->resp_headers)
-        {
+        if(!state->resp_headers) {
             return CURLE_WRITE_ERROR;
         }
 
@@ -598,26 +511,22 @@ recv_header(void *ptr, size_t size, size
     }
 
     // We get a notice at the \r\n\r\n after headers.
-    if(length <= 2)
-    {
+    if(length <= 2) {
         return length;
     }
 
     // Append the new header to our array.
     hdr = dec_string(state->cx, header, length);
-    if(!hdr)
-    {
+    if(!hdr) {
         return CURLE_WRITE_ERROR;
     }
 
-    if(!JS_GetArrayLength(state->cx, state->resp_headers, &hdrlen))
-    {
+    if(!JS_GetArrayLength(state->cx, state->resp_headers, &hdrlen)) {
         return CURLE_WRITE_ERROR;
     }
 
     hdrval = STRING_TO_JSVAL(hdr);
-    if(!JS_SetElement(state->cx, state->resp_headers, hdrlen, &hdrval))
-    {
+    if(!JS_SetElement(state->cx, state->resp_headers, hdrlen, &hdrval)) {
         return CURLE_WRITE_ERROR;
     }
 
@@ -631,15 +540,13 @@ recv_body(void *ptr, size_t size, size_t
     size_t length = size * nmem;
     char* tmp = NULL;
     
-    if(!state->recvbuf)
-    {
+    if(!state->recvbuf) {
         state->recvlen = 4096;
         state->read = 0;
         state->recvbuf = JS_malloc(state->cx, state->recvlen);
     }
     
-    if(!state->recvbuf)
-    {
+    if(!state->recvbuf) {
         return CURLE_WRITE_ERROR;
     }
 
@@ -663,8 +570,7 @@ str_from_binary(JSContext* cx, char* dat
 
     if(!conv) return NULL;
 
-    for(i = 0; i < length; i++)
-    {
+    for(i = 0; i < length; i++) {
         conv[i] = (jschar) data[i];
     }
 

Modified: couchdb/branches/1.1.x/src/couchdb/priv/couch_js/http.h
URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/src/couchdb/priv/couch_js/http.h?rev=1166525&r1=1166524&r2=1166525&view=diff
==============================================================================
--- couchdb/branches/1.1.x/src/couchdb/priv/couch_js/http.h (original)
+++ couchdb/branches/1.1.x/src/couchdb/priv/couch_js/http.h Thu Sep  8 05:00:10 2011
@@ -13,6 +13,12 @@
 #ifndef COUCH_JS_HTTP_H
 #define COUCH_JS_HTTP_H
 
-JSObject* install_http(JSContext* cx, JSObject* global);
+void http_check_enabled();
+JSBool http_ctor(JSContext* cx, JSObject* req);
+void http_dtor(JSContext* cx, JSObject* req);
+JSBool http_open(JSContext* cx, JSObject* req, jsval mth, jsval url, jsval snc);
+JSBool http_set_hdr(JSContext* cx, JSObject* req, jsval name, jsval val);
+JSBool http_send(JSContext* cx, JSObject* req, jsval body);
+int http_status(JSContext* cx, JSObject* req);
 
-#endif
\ No newline at end of file
+#endif

Modified: couchdb/branches/1.1.x/src/couchdb/priv/couch_js/main.c
URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/src/couchdb/priv/couch_js/main.c?rev=1166525&r1=1166524&r2=1166525&view=diff
==============================================================================
--- couchdb/branches/1.1.x/src/couchdb/priv/couch_js/main.c (original)
+++ couchdb/branches/1.1.x/src/couchdb/priv/couch_js/main.c Thu Sep  8 05:00:10 2011
@@ -10,329 +10,12 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <jsapi.h>
 #include "config.h"
 
-#include "utf8.h"
-#include "http.h"
-
-int gExitCode = 0;
-
-#ifdef JS_THREADSAFE
-#define SETUP_REQUEST(cx) \
-    JS_SetContextThread(cx); \
-    JS_BeginRequest(cx);
-#define FINISH_REQUEST(cx) \
-    JS_EndRequest(cx); \
-    JS_ClearContextThread(cx);
+#if defined(SM185)
+#include "sm185.c"
+#elif defined(SM180)
+#include "sm180.c"
 #else
-#define SETUP_REQUEST(cx)
-#define FINISH_REQUEST(cx)
+#include "sm170.c"
 #endif
-
-static JSBool
-evalcx(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
-    JSString *str;
-    JSObject *sandbox;
-    JSContext *subcx;
-    const jschar *src;
-    size_t srclen;
-    JSBool ret = JS_FALSE;
-    jsval v;
-
-    sandbox = NULL;
-    if(!JS_ConvertArguments(cx, argc, argv, "S / o", &str, &sandbox))
-    {
-        return JS_FALSE;
-    }
-
-    subcx = JS_NewContext(JS_GetRuntime(cx), 8L * 1024L);
-    if(!subcx)
-    {
-        JS_ReportOutOfMemory(cx);
-        return JS_FALSE;
-    }
-
-    SETUP_REQUEST(subcx);
-
-    src = JS_GetStringChars(str);
-    srclen = JS_GetStringLength(str);
-
-    if(!sandbox)
-    {
-        sandbox = JS_NewObject(subcx, NULL, NULL, NULL);
-        if(!sandbox || !JS_InitStandardClasses(subcx, sandbox)) goto done;
-    }
-
-    if(srclen == 0)
-    {
-        *rval = OBJECT_TO_JSVAL(sandbox);
-    }
-    else
-    {
-        JS_EvaluateUCScript(subcx, sandbox, src, srclen, NULL, 0, rval);
-    }
-    
-    ret = JS_TRUE;
-
-done:
-    FINISH_REQUEST(subcx);
-    JS_DestroyContext(subcx);
-    return ret;
-}
-
-static JSBool
-gc(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
-    JS_GC(cx);
-    return JS_TRUE;
-}
-
-static JSBool
-print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
-    uintN i;
-    char *bytes;
-
-    for(i = 0; i < argc; i++)
-    {
-        bytes = enc_string(cx, argv[i], NULL);
-        if(!bytes) return JS_FALSE;
-
-        fprintf(stdout, "%s%s", i ? " " : "", bytes);
-        JS_free(cx, bytes);
-    }
-
-    fputc('\n', stdout);
-    fflush(stdout);
-    return JS_TRUE;
-}
-
-static JSBool
-quit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
-    JS_ConvertArguments(cx, argc, argv, "/ i", &gExitCode);
-    return JS_FALSE;
-}
-
-static char*
-readfp(JSContext* cx, FILE* fp, size_t* buflen)
-{
-    char* bytes = NULL;
-    char* tmp = NULL;
-    size_t used = 0;
-    size_t byteslen = 256;
-    size_t readlen = 0;
-
-    bytes = JS_malloc(cx, byteslen);
-    if(bytes == NULL) return NULL;
-    
-    while((readlen = js_fgets(bytes+used, byteslen-used, stdin)) > 0)
-    {
-        used += readlen;
-
-        if(bytes[used-1] == '\n')
-        {
-            bytes[used-1] = '\0';
-            break;
-        }
-
-        // Double our buffer and read more.
-        byteslen *= 2;
-        tmp = JS_realloc(cx, bytes, byteslen);
-        if(!tmp)
-        {
-            JS_free(cx, bytes);
-            return NULL;
-        }
-        bytes = tmp;
-    }
-
-    *buflen = used;
-    return bytes;
-}
-
-static JSBool
-readline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
-    jschar *chars;
-    JSString *str;
-    char* bytes;
-    char* tmp;
-    size_t byteslen;
-
-    /* GC Occasionally */
-    JS_MaybeGC(cx);
-
-    bytes = readfp(cx, stdin, &byteslen);
-    if(!bytes) return JS_FALSE;
-    
-    /* Treat the empty string specially */
-    if(byteslen == 0)
-    {
-        *rval = JS_GetEmptyStringValue(cx);
-        JS_free(cx, bytes);
-        return JS_TRUE;
-    }
-
-    /* Shrink the buffer to the real size */
-    tmp = JS_realloc(cx, bytes, byteslen);
-    if(!tmp)
-    {
-        JS_free(cx, bytes);
-        return JS_FALSE;
-    }
-    bytes = tmp;
-    
-    str = dec_string(cx, bytes, byteslen);
-    JS_free(cx, bytes);
-
-    if(!str) return JS_FALSE;
-
-    *rval = STRING_TO_JSVAL(str);
-
-    return JS_TRUE;
-}
-
-static JSBool
-seal(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
-    JSObject *target;
-    JSBool deep = JS_FALSE;
-
-    if (!JS_ConvertArguments(cx, argc, argv, "o/b", &target, &deep))
-        return JS_FALSE;
-    if (!target)
-        return JS_TRUE;
-    return JS_SealObject(cx, target, deep);
-}
-
-static void
-execute_script(JSContext *cx, JSObject *obj, const char *filename) {
-    FILE *file;
-    JSScript *script;
-    jsval result;
-
-    if(!filename || strcmp(filename, "-") == 0)
-    {
-        file = stdin;
-    }
-    else
-    {
-        file = fopen(filename, "r");
-        if (!file)
-        {
-            fprintf(stderr, "could not open script file %s\n", filename);
-            gExitCode = 1;
-            return;
-        }
-    }
-
-    script = JS_CompileFileHandle(cx, obj, filename, file);
-    if(script)
-    {
-        JS_ExecuteScript(cx, obj, script, &result);
-        JS_DestroyScript(cx, script);
-    }
-}
-
-static void
-printerror(JSContext *cx, const char *mesg, JSErrorReport *report)
-{
-    if(!report || !JSREPORT_IS_WARNING(report->flags))
-    {
-        fprintf(stderr, "%s\n", mesg);
-    }
-}
-
-static JSFunctionSpec global_functions[] = {
-    {"evalcx", evalcx, 0, 0, 0},
-    {"gc", gc, 0, 0, 0},
-    {"print", print, 0, 0, 0},
-    {"quit", quit, 0, 0, 0},
-    {"readline", readline, 0, 0, 0},
-    {"seal", seal, 0, 0, 0},
-    {0, 0, 0, 0, 0}
-};
-
-static JSClass global_class = {
-    "GlobalClass",
-    JSCLASS_GLOBAL_FLAGS,
-    JS_PropertyStub,
-    JS_PropertyStub,
-    JS_PropertyStub,
-    JS_PropertyStub,
-    JS_EnumerateStub,
-    JS_ResolveStub,
-    JS_ConvertStub,
-    JS_FinalizeStub,
-    JSCLASS_NO_OPTIONAL_MEMBERS
-};
-
-int
-main(int argc, const char * argv[])
-{
-    JSRuntime* rt = NULL;
-    JSContext* cx = NULL;
-    JSObject* global = NULL;
-    JSFunctionSpec* sp = NULL;
-    int i = 0;
-    
-    rt = JS_NewRuntime(64L * 1024L * 1024L);
-    if (!rt) return 1;
-
-    cx = JS_NewContext(rt, 8L * 1024L);
-    if (!cx) return 1;
-
-    JS_SetErrorReporter(cx, printerror);
-    JS_ToggleOptions(cx, JSOPTION_XML);
-    
-    SETUP_REQUEST(cx);
-
-    global = JS_NewObject(cx, &global_class, NULL, NULL);
-    if (!global) return 1;
-    if (!JS_InitStandardClasses(cx, global)) return 1;
-    
-    for(sp = global_functions; sp->name != NULL; sp++)
-    {
-        if(!JS_DefineFunction(cx, global,
-               sp->name, sp->call, sp->nargs, sp->flags))
-        {
-            fprintf(stderr, "Failed to create function: %s\n", sp->name);
-            return 1;
-        }
-    }
-
-    if(!install_http(cx, global))
-    {
-        return 1;
-    }
-    
-    JS_SetGlobalObject(cx, global);
-
-    if(argc > 2)
-    {
-        fprintf(stderr, "incorrect number of arguments\n\n");
-        fprintf(stderr, "usage: %s <scriptfile>\n", argv[0]);
-        return 2;
-    }
-
-    if(argc == 0)
-    {
-        execute_script(cx, global, NULL);
-    }
-    else
-    {
-        execute_script(cx, global, argv[1]);
-    }
-
-    FINISH_REQUEST(cx);
-
-    JS_DestroyContext(cx);
-    JS_DestroyRuntime(rt);
-    JS_ShutDown();
-
-    return gExitCode;
-}

Modified: couchdb/branches/1.1.x/src/couchdb/priv/couch_js/utf8.c
URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/src/couchdb/priv/couch_js/utf8.c?rev=1166525&r1=1166524&r2=1166525&view=diff
==============================================================================
--- couchdb/branches/1.1.x/src/couchdb/priv/couch_js/utf8.c (original)
+++ couchdb/branches/1.1.x/src/couchdb/priv/couch_js/utf8.c Thu Sep  8 05:00:10 2011
@@ -11,6 +11,7 @@
 // the License.
 
 #include <jsapi.h>
+#include "config.h"
 
 static int
 enc_char(uint8 *utf8Buffer, uint32 ucs4Char)
@@ -121,7 +122,7 @@ char*
 enc_string(JSContext* cx, jsval arg, size_t* buflen)
 {
     JSString* str = NULL;
-    jschar* src = NULL;
+    const jschar* src = NULL;
     char* bytes = NULL;
     size_t srclen = 0;
     size_t byteslen = 0;
@@ -129,8 +130,12 @@ enc_string(JSContext* cx, jsval arg, siz
     str = JS_ValueToString(cx, arg);
     if(!str) goto error;
 
+#ifdef HAVE_JS_GET_STRING_CHARS_AND_LENGTH
+    src = JS_GetStringCharsAndLength(cx, str, &srclen);
+#else
     src = JS_GetStringChars(str);
     srclen = JS_GetStringLength(str);
+#endif
 
     if(!enc_charbuf(src, srclen, NULL, &byteslen)) goto error;
     
@@ -283,4 +288,4 @@ error:
 
 success:
     return str;
-}
\ No newline at end of file
+}

Modified: couchdb/branches/1.1.x/test/javascript/run.tpl
URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/test/javascript/run.tpl?rev=1166525&r1=1166524&r2=1166525&view=diff
==============================================================================
--- couchdb/branches/1.1.x/test/javascript/run.tpl (original)
+++ couchdb/branches/1.1.x/test/javascript/run.tpl Thu Sep  8 05:00:10 2011
@@ -27,4 +27,4 @@ cat $SCRIPT_DIR/json2.js \
 	$SCRIPT_DIR/test/*.js \
 	$JS_TEST_DIR/couch_http.js \
 	$JS_TEST_DIR/cli_runner.js \
-    | $COUCHJS -
+    | $COUCHJS --http -



Mime
View raw message