summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoan Touzet <wohali@users.noreply.github.com>2020-10-07 17:29:15 +0000
committerGitHub <noreply@github.com>2020-10-07 13:29:15 -0400
commit6b23f20bd70b933988ebeb888cb6d39b308f8742 (patch)
tree32dbbbfab9454cd51991a2ac05e6d941c6512226 /src
parentf2c30fe388dc96d00265ed2f7f99b33df8eabfc0 (diff)
downloadcouchdb-6b23f20bd70b933988ebeb888cb6d39b308f8742.tar.gz
Remove JS tests + support for harness (#3197)
Diffstat (limited to 'src')
-rw-r--r--src/couch/priv/couch_js/1.8.5/help.h7
-rw-r--r--src/couch/priv/couch_js/1.8.5/http.c701
-rw-r--r--src/couch/priv/couch_js/1.8.5/http.h27
-rw-r--r--src/couch/priv/couch_js/1.8.5/main.c182
-rw-r--r--src/couch/priv/couch_js/1.8.5/util.c2
-rw-r--r--src/couch/priv/couch_js/1.8.5/util.h2
-rw-r--r--src/couch/priv/couch_js/60/help.h7
-rw-r--r--src/couch/priv/couch_js/60/http.cpp649
-rw-r--r--src/couch/priv/couch_js/60/http.h27
-rw-r--r--src/couch/priv/couch_js/60/main.cpp193
-rw-r--r--src/couch/priv/couch_js/60/util.cpp10
-rw-r--r--src/couch/priv/couch_js/60/util.h4
-rw-r--r--src/couch/priv/couch_js/68/help.h7
-rw-r--r--src/couch/priv/couch_js/68/http.cpp650
-rw-r--r--src/couch/priv/couch_js/68/http.h27
-rw-r--r--src/couch/priv/couch_js/68/main.cpp198
-rw-r--r--src/couch/priv/couch_js/68/util.cpp10
-rw-r--r--src/couch/rebar.config.script31
18 files changed, 4 insertions, 2730 deletions
diff --git a/src/couch/priv/couch_js/1.8.5/help.h b/src/couch/priv/couch_js/1.8.5/help.h
index 335935ed0..3a19901f0 100644
--- a/src/couch/priv/couch_js/1.8.5/help.h
+++ b/src/couch/priv/couch_js/1.8.5/help.h
@@ -46,15 +46,9 @@ static const char USAGE_TEMPLATE[] =
"\n"
" -h display a short help message and exit\n"
" -V display version information and exit\n"
- " -H enable %s cURL bindings (only avaiable\n"
- " if package was built with cURL available)\n"
- " -T enable test suite specific functions (these\n"
- " should not be enabled for production systems)\n"
" -S SIZE specify that the runtime should allow at\n"
" most SIZE bytes of memory to be allocated\n"
" default is 64 MiB\n"
- " -u FILE path to a .uri file containing the address\n"
- " (or addresses) of one or more servers\n"
" --eval Enable runtime code evaluation (dangerous!)\n"
"\n"
"Report bugs at <%s>.\n";
@@ -78,7 +72,6 @@ static const char USAGE_TEMPLATE[] =
basename, \
basename, \
PACKAGE_NAME, \
- basename, \
PACKAGE_BUGREPORT)
#define DISPLAY_USAGE couch_usage(BASENAME)
diff --git a/src/couch/priv/couch_js/1.8.5/http.c b/src/couch/priv/couch_js/1.8.5/http.c
deleted file mode 100644
index c4b389659..000000000
--- a/src/couch/priv/couch_js/1.8.5/http.c
+++ /dev/null
@@ -1,701 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <jsapi.h>
-#include "config.h"
-#include "utf8.h"
-#include "util.h"
-
-// Soft dependency on cURL bindings because they're
-// only used when running the JS tests from the
-// command line which is rare.
-#ifndef HAVE_CURL
-
-void
-http_check_enabled()
-{
- fprintf(stderr, "HTTP API was disabled at compile time.\n");
- exit(3);
-}
-
-
-JSBool
-http_ctor(JSContext* cx, JSObject* req)
-{
- return JS_FALSE;
-}
-
-
-JSBool
-http_dtor(JSContext* cx, JSObject* req)
-{
- return JS_FALSE;
-}
-
-
-JSBool
-http_open(JSContext* cx, JSObject* req, jsval mth, jsval url, jsval snc)
-{
- return JS_FALSE;
-}
-
-
-JSBool
-http_set_hdr(JSContext* cx, JSObject* req, jsval name, jsval val)
-{
- return JS_FALSE;
-}
-
-
-JSBool
-http_send(JSContext* cx, JSObject* req, jsval body)
-{
- return JS_FALSE;
-}
-
-
-int
-http_status(JSContext* cx, JSObject* req, jsval body)
-{
- return -1;
-}
-
-JSBool
-http_uri(JSContext* cx, JSObject* req, couch_args* args, jsval* uri_val)
-{
- return JS_FALSE;
-}
-
-
-#else
-#include <curl/curl.h>
-#ifndef XP_WIN
-#include <unistd.h>
-#endif
-
-
-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;
- CurlHeaders* req_headers;
- jsint last_status;
-} HTTPData;
-
-
-char* METHODS[] = {"GET", "HEAD", "POST", "PUT", "DELETE", "COPY", "OPTIONS", NULL};
-
-
-#define GET 0
-#define HEAD 1
-#define POST 2
-#define PUT 3
-#define DELETE 4
-#define COPY 5
-#define OPTIONS 6
-
-
-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);
-
-
-JSBool
-http_ctor(JSContext* cx, JSObject* req)
-{
- HTTPData* http = NULL;
- JSBool ret = JS_FALSE;
-
- http = (HTTPData*) malloc(sizeof(HTTPData));
- if(!http)
- {
- JS_ReportError(cx, "Failed to create CouchHTTP instance.");
- goto error;
- }
-
- http->method = -1;
- http->url = NULL;
- http->req_headers = NULL;
- http->last_status = -1;
-
- if(!JS_SetPrivate(cx, req, http))
- {
- JS_ReportError(cx, "Failed to set private CouchHTTP data.");
- goto error;
- }
-
- ret = JS_TRUE;
- goto success;
-
-error:
- if(http) free(http);
-
-success:
- return ret;
-}
-
-
-void
-http_dtor(JSContext* cx, JSObject* obj)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj);
- if(http) {
- if(http->url) free(http->url);
- if(http->req_headers) curl_slist_free_all(http->req_headers);
- free(http);
- }
-}
-
-
-JSBool
-http_open(JSContext* cx, JSObject* req, jsval mth, jsval url, jsval snc)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(cx, req);
- char* method = NULL;
- int methid;
- JSBool ret = JS_FALSE;
-
- if(!http) {
- JS_ReportError(cx, "Invalid CouchHTTP instance.");
- goto done;
- }
-
- if(JSVAL_IS_VOID(mth)) {
- JS_ReportError(cx, "You must specify a method.");
- goto done;
- }
-
- method = enc_string(cx, mth, NULL);
- if(!method) {
- JS_ReportError(cx, "Failed to encode method.");
- goto done;
- }
-
- for(methid = 0; METHODS[methid] != NULL; methid++) {
- if(strcasecmp(METHODS[methid], method) == 0) break;
- }
-
- if(methid > OPTIONS) {
- JS_ReportError(cx, "Invalid method specified.");
- goto done;
- }
-
- http->method = methid;
-
- if(JSVAL_IS_VOID(url)) {
- JS_ReportError(cx, "You must specify a URL.");
- goto done;
- }
-
- if(http->url != NULL) {
- free(http->url);
- http->url = NULL;
- }
-
- http->url = enc_string(cx, url, NULL);
- if(http->url == NULL) {
- JS_ReportError(cx, "Failed to encode URL.");
- goto done;
- }
-
- if(JSVAL_IS_BOOLEAN(snc) && JSVAL_TO_BOOLEAN(snc)) {
- JS_ReportError(cx, "Synchronous flag must be false.");
- goto done;
- }
-
- if(http->req_headers) {
- curl_slist_free_all(http->req_headers);
- http->req_headers = NULL;
- }
-
- // Disable Expect: 100-continue
- http->req_headers = curl_slist_append(http->req_headers, "Expect:");
-
- ret = JS_TRUE;
-
-done:
- if(method) free(method);
- return ret;
-}
-
-
-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) {
- JS_ReportError(cx, "Invalid CouchHTTP instance.");
- goto done;
- }
-
- if(JSVAL_IS_VOID(name))
- {
- JS_ReportError(cx, "You must speciy a header name.");
- goto done;
- }
-
- keystr = enc_string(cx, name, NULL);
- if(!keystr)
- {
- JS_ReportError(cx, "Failed to encode header name.");
- goto done;
- }
-
- if(JSVAL_IS_VOID(val))
- {
- JS_ReportError(cx, "You must specify a header value.");
- goto done;
- }
-
- valstr = enc_string(cx, val, NULL);
- if(!valstr)
- {
- JS_ReportError(cx, "Failed to encode header value.");
- goto done;
- }
-
- hdrlen = strlen(keystr) + strlen(valstr) + 3;
- hdrbuf = (char*) malloc(hdrlen * sizeof(char));
- if(!hdrbuf) {
- JS_ReportError(cx, "Failed to allocate header buffer.");
- goto done;
- }
-
- snprintf(hdrbuf, hdrlen, "%s: %s", keystr, valstr);
- http->req_headers = curl_slist_append(http->req_headers, hdrbuf);
-
- ret = JS_TRUE;
-
-done:
- if(keystr) free(keystr);
- if(valstr) free(valstr);
- if(hdrbuf) free(hdrbuf);
- return ret;
-}
-
-JSBool
-http_send(JSContext* cx, JSObject* req, jsval body)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(cx, req);
- char* bodystr = NULL;
- size_t bodylen = 0;
- JSBool ret = JS_FALSE;
-
- if(!http) {
- JS_ReportError(cx, "Invalid CouchHTTP instance.");
- goto done;
- }
-
- if(!JSVAL_IS_VOID(body)) {
- bodystr = enc_string(cx, body, &bodylen);
- if(!bodystr) {
- JS_ReportError(cx, "Failed to encode body.");
- goto done;
- }
- }
-
- ret = go(cx, req, http, bodystr, bodylen);
-
-done:
- if(bodystr) free(bodystr);
- return ret;
-}
-
-int
-http_status(JSContext* cx, JSObject* req)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(cx, req);
-
- if(!http) {
- JS_ReportError(cx, "Invalid CouchHTTP instance.");
- return JS_FALSE;
- }
-
- return http->last_status;
-}
-
-JSBool
-http_uri(JSContext* cx, JSObject* req, couch_args* args, jsval* uri_val)
-{
- FILE* uri_fp = NULL;
- JSString* uri_str;
-
- // Default is http://localhost:15986/ when no uri file is specified
- if (!args->uri_file) {
- uri_str = JS_InternString(cx, "http://localhost:15986/");
- *uri_val = STRING_TO_JSVAL(uri_str);
- JS_SetReservedSlot(cx, req, 0, *uri_val);
- return JS_TRUE;
- }
-
- // Else check to see if the base url is cached in a reserved slot
- if (JS_GetReservedSlot(cx, req, 0, uri_val) && !JSVAL_IS_VOID(*uri_val)) {
- return JS_TRUE;
- }
-
- // Read the first line of the couch.uri file.
- if(!((uri_fp = fopen(args->uri_file, "r")) &&
- (uri_str = couch_readline(cx, uri_fp)))) {
- JS_ReportError(cx, "Failed to read couch.uri file.");
- goto error;
- }
-
- fclose(uri_fp);
- *uri_val = STRING_TO_JSVAL(uri_str);
- JS_SetReservedSlot(cx, req, 0, *uri_val);
- return JS_TRUE;
-
-error:
- if(uri_fp) fclose(uri_fp);
- return JS_FALSE;
-}
-
-
-// Curl Helpers
-
-typedef struct {
- HTTPData* http;
- JSContext* cx;
- JSObject* resp_headers;
- char* sendbuf;
- size_t sendlen;
- size_t sent;
- int sent_once;
- char* recvbuf;
- size_t recvlen;
- size_t read;
-} CurlState;
-
-/*
- * I really hate doing this but this doesn't have to be
- * uber awesome, it just has to work.
- */
-CURL* HTTP_HANDLE = NULL;
-char ERRBUF[CURL_ERROR_SIZE];
-
-static size_t send_body(void *ptr, size_t size, size_t nmem, void *data);
-static int seek_body(void *ptr, curl_off_t offset, int origin);
-static size_t recv_body(void *ptr, size_t size, size_t nmem, void *data);
-static size_t recv_header(void *ptr, size_t size, size_t nmem, void *data);
-
-static JSBool
-go(JSContext* cx, JSObject* obj, HTTPData* http, char* body, size_t bodylen)
-{
- CurlState state;
- char* referer;
- JSString* jsbody;
- JSBool ret = JS_FALSE;
- jsval tmp;
-
- state.cx = cx;
- state.http = http;
-
- 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) {
- HTTP_HANDLE = curl_easy_init();
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_READFUNCTION, send_body);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_SEEKFUNCTION,
- (curl_seek_callback) seek_body);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_HEADERFUNCTION, recv_header);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEFUNCTION, recv_body);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOPROGRESS, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_ERRORBUFFER, ERRBUF);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_COOKIEFILE, "");
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_USERAGENT,
- "CouchHTTP Client - Relax");
- }
-
- if(!HTTP_HANDLE) {
- JS_ReportError(cx, "Failed to initialize cURL handle.");
- goto done;
- }
-
- if(!JS_GetReservedSlot(cx, obj, 0, &tmp)) {
- JS_ReportError(cx, "Failed to readreserved slot.");
- goto done;
- }
-
- if(!(referer = enc_string(cx, tmp, NULL))) {
- JS_ReportError(cx, "Failed to encode referer.");
- goto done;
- }
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_REFERER, referer);
- free(referer);
-
- if(http->method < 0 || http->method > OPTIONS) {
- JS_ReportError(cx, "INTERNAL: Unknown method.");
- goto done;
- }
-
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_CUSTOMREQUEST, METHODS[http->method]);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOBODY, 0);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 0);
-
- 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) {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 0);
- }
-
- if(body && bodylen) {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, bodylen);
- } else {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, 0);
- }
-
- // 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);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_READDATA, &state);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_SEEKDATA, &state);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEHEADER, &state);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEDATA, &state);
-
- if(curl_easy_perform(HTTP_HANDLE) != 0) {
- JS_ReportError(cx, "Failed to execute HTTP request: %s", ERRBUF);
- goto done;
- }
-
- 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,
- "_headers",
- tmp,
- NULL, NULL,
- JSPROP_READONLY
- )) {
- JS_ReportError(cx, "INTERNAL: Failed to set response headers.");
- goto done;
- }
-
- if(state.recvbuf) {
- state.recvbuf[state.read] = '\0';
- jsbody = dec_string(cx, state.recvbuf, state.read+1);
- 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.
- jsbody = str_from_binary(cx, state.recvbuf, state.read);
- if(!jsbody) {
- if(!JS_IsExceptionPending(cx)) {
- JS_ReportError(cx, "INTERNAL: Failed to decode body.");
- }
- goto done;
- }
- }
- tmp = STRING_TO_JSVAL(jsbody);
- } else {
- tmp = JS_GetEmptyStringValue(cx);
- }
-
- if(!JS_DefineProperty(
- cx, obj,
- "responseText",
- tmp,
- NULL, NULL,
- JSPROP_READONLY
- )) {
- JS_ReportError(cx, "INTERNAL: Failed to set responseText.");
- goto done;
- }
-
- ret = JS_TRUE;
-
-done:
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
-}
-
-static size_t
-send_body(void *ptr, size_t size, size_t nmem, void *data)
-{
- CurlState* state = (CurlState*) data;
- size_t length = size * nmem;
- size_t towrite = state->sendlen - state->sent;
-
- // 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;
-
- memcpy(ptr, state->sendbuf + state->sent, towrite);
- state->sent += towrite;
-
- return towrite;
-}
-
-static int
-seek_body(void* ptr, curl_off_t offset, int origin)
-{
- CurlState* state = (CurlState*) ptr;
- if(origin != SEEK_SET) return -1;
-
- state->sent = (size_t) offset;
- return (int) state->sent;
-}
-
-static size_t
-recv_header(void *ptr, size_t size, size_t nmem, void *data)
-{
- CurlState* state = (CurlState*) data;
- char code[4];
- char* header = (char*) ptr;
- size_t length = size * nmem;
- JSString* hdr = NULL;
- jsuint hdrlen;
- jsval hdrval;
-
- if(length > 7 && strncasecmp(header, "HTTP/1.", 7) == 0) {
- if(length < 12) {
- return CURLE_WRITE_ERROR;
- }
-
- memcpy(code, header+9, 3*sizeof(char));
- code[3] = '\0';
- state->http->last_status = atoi(code);
-
- state->resp_headers = JS_NewArrayObject(state->cx, 0, NULL);
- if(!state->resp_headers) {
- return CURLE_WRITE_ERROR;
- }
-
- return length;
- }
-
- // We get a notice at the \r\n\r\n after headers.
- if(length <= 2) {
- return length;
- }
-
- // Append the new header to our array.
- hdr = dec_string(state->cx, header, length);
- if(!hdr) {
- return CURLE_WRITE_ERROR;
- }
-
- 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)) {
- return CURLE_WRITE_ERROR;
- }
-
- return length;
-}
-
-static size_t
-recv_body(void *ptr, size_t size, size_t nmem, void *data)
-{
- CurlState* state = (CurlState*) data;
- size_t length = size * nmem;
- char* tmp = NULL;
-
- if(!state->recvbuf) {
- state->recvlen = 4096;
- state->read = 0;
- state->recvbuf = JS_malloc(state->cx, state->recvlen);
- }
-
- if(!state->recvbuf) {
- return CURLE_WRITE_ERROR;
- }
-
- // +1 so we can add '\0' back up in the go function.
- while(length+1 > state->recvlen - state->read) state->recvlen *= 2;
- tmp = JS_realloc(state->cx, state->recvbuf, state->recvlen);
- if(!tmp) return CURLE_WRITE_ERROR;
- state->recvbuf = tmp;
-
- memcpy(state->recvbuf + state->read, ptr, length);
- state->read += length;
- return length;
-}
-
-JSString*
-str_from_binary(JSContext* cx, char* data, size_t length)
-{
- jschar* conv = (jschar*) JS_malloc(cx, length * sizeof(jschar));
- JSString* ret = NULL;
- size_t i;
-
- if(!conv) return NULL;
-
- for(i = 0; i < length; i++) {
- conv[i] = (jschar) data[i];
- }
-
- ret = JS_NewUCString(cx, conv, length);
- if(!ret) JS_free(cx, conv);
-
- return ret;
-}
-
-#endif /* HAVE_CURL */
diff --git a/src/couch/priv/couch_js/1.8.5/http.h b/src/couch/priv/couch_js/1.8.5/http.h
deleted file mode 100644
index 63d45bd06..000000000
--- a/src/couch/priv/couch_js/1.8.5/http.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-#ifndef COUCH_JS_HTTP_H
-#define COUCH_JS_HTTP_H
-
-#include "util.h"
-
-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);
-JSBool http_uri(JSContext* cx, JSObject *req, couch_args* args, jsval* uri);
-
-#endif
diff --git a/src/couch/priv/couch_js/1.8.5/main.c b/src/couch/priv/couch_js/1.8.5/main.c
index 986791c90..c8e385cc9 100644
--- a/src/couch/priv/couch_js/1.8.5/main.c
+++ b/src/couch/priv/couch_js/1.8.5/main.c
@@ -22,7 +22,6 @@
#include <jsapi.h>
#include "config.h"
-#include "http.h"
#include "utf8.h"
#include "util.h"
@@ -49,105 +48,6 @@ static JSClass global_class = {
JSCLASS_NO_OPTIONAL_MEMBERS
};
-
-static JSBool
-req_ctor(JSContext* cx, uintN argc, jsval* vp)
-{
- JSBool ret;
- JSObject* obj = JS_NewObjectForConstructor(cx, vp);
- if(!obj) {
- JS_ReportError(cx, "Failed to create CouchHTTP instance.\n");
- return JS_FALSE;
- }
- ret = http_ctor(cx, obj);
- JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
- return ret;
-}
-
-
-static void
-req_dtor(JSContext* cx, JSObject* obj)
-{
- http_dtor(cx, obj);
-}
-
-
-static JSBool
-req_open(JSContext* cx, uintN argc, jsval* vp)
-{
- JSObject* obj = JS_THIS_OBJECT(cx, vp);
- jsval* argv = JS_ARGV(cx, vp);
- JSBool ret = JS_FALSE;
-
- if(argc == 2) {
- ret = http_open(cx, obj, argv[0], argv[1], JSVAL_FALSE);
- } else if(argc == 3) {
- ret = http_open(cx, obj, argv[0], argv[1], argv[2]);
- } else {
- JS_ReportError(cx, "Invalid call to CouchHTTP.open");
- }
-
- JS_SET_RVAL(cx, vp, JSVAL_VOID);
- return ret;
-}
-
-
-static JSBool
-req_set_hdr(JSContext* cx, uintN argc, jsval* vp)
-{
- JSObject* obj = JS_THIS_OBJECT(cx, vp);
- jsval* argv = JS_ARGV(cx, vp);
- JSBool ret = JS_FALSE;
-
- if(argc == 2) {
- ret = http_set_hdr(cx, obj, argv[0], argv[1]);
- } else {
- JS_ReportError(cx, "Invalid call to CouchHTTP.set_header");
- }
-
- JS_SET_RVAL(cx, vp, JSVAL_VOID);
- return ret;
-}
-
-
-static JSBool
-req_send(JSContext* cx, uintN argc, jsval* vp)
-{
- JSObject* obj = JS_THIS_OBJECT(cx, vp);
- jsval* argv = JS_ARGV(cx, vp);
- JSBool ret = JS_FALSE;
-
- if(argc == 1) {
- ret = http_send(cx, obj, argv[0]);
- } else {
- JS_ReportError(cx, "Invalid call to CouchHTTP.send");
- }
-
- JS_SET_RVAL(cx, vp, JSVAL_VOID);
- return ret;
-}
-
-
-static JSBool
-req_status(JSContext* cx, JSObject* obj, jsid pid, jsval* vp)
-{
- int status = http_status(cx, obj);
- if(status < 0)
- return JS_FALSE;
-
- JS_SET_RVAL(cx, vp, INT_TO_JSVAL(status));
- return JS_TRUE;
-}
-
-
-static JSBool
-base_url(JSContext *cx, JSObject* obj, jsid pid, jsval* vp)
-{
- couch_args *args = (couch_args*)JS_GetContextPrivate(cx);
- return http_uri(cx, obj, args, &JS_RVAL(cx, vp));
-}
-
-
static JSBool
evalcx(JSContext *cx, uintN argc, jsval* vp)
{
@@ -281,63 +181,6 @@ seal(JSContext* cx, uintN argc, jsval* vp)
}
-static JSBool
-js_sleep(JSContext* cx, uintN argc, jsval* vp)
-{
- jsval* argv = JS_ARGV(cx, vp);
- int duration = 0;
- if(!JS_ConvertArguments(cx, argc, argv, "/i", &duration)) {
- return JS_FALSE;
- }
-
-#ifdef XP_WIN
- Sleep(duration);
-#else
- usleep(duration * 1000);
-#endif
-
- return JS_TRUE;
-}
-
-
-JSClass CouchHTTPClass = {
- "CouchHTTP",
- JSCLASS_HAS_PRIVATE
- | JSCLASS_CONSTRUCT_PROTOTYPE
- | JSCLASS_HAS_RESERVED_SLOTS(2),
- JS_PropertyStub,
- JS_PropertyStub,
- JS_PropertyStub,
- JS_StrictPropertyStub,
- JS_EnumerateStub,
- JS_ResolveStub,
- JS_ConvertStub,
- req_dtor,
- JSCLASS_NO_OPTIONAL_MEMBERS
-};
-
-
-JSPropertySpec CouchHTTPProperties[] = {
- {"status", 0, JSPROP_READONLY, req_status, NULL},
- {"base_url", 0, JSPROP_READONLY | JSPROP_SHARED, base_url, NULL},
- {0, 0, 0, 0, 0}
-};
-
-
-JSFunctionSpec CouchHTTPFunctions[] = {
- JS_FS("_open", req_open, 3, 0),
- JS_FS("_setRequestHeader", req_set_hdr, 2, 0),
- JS_FS("_send", req_send, 1, 0),
- JS_FS_END
-};
-
-
-JSFunctionSpec TestSuiteFunctions[] = {
- JS_FS("sleep", js_sleep, 1, 0),
- JS_FS_END
-};
-
-
static JSFunctionSpec global_functions[] = {
JS_FS("evalcx", evalcx, 0, 0),
JS_FS("gc", gc, 0, 0),
@@ -376,7 +219,6 @@ main(int argc, const char* argv[])
JSContext* cx = NULL;
JSObject* global = NULL;
JSCrossCompartmentCall *call = NULL;
- JSObject* klass = NULL;
JSSCRIPT_TYPE script;
JSString* scriptsrc;
const jschar* schars;
@@ -420,30 +262,6 @@ main(int argc, const char* argv[])
if(couch_load_funcs(cx, global, global_functions) != JS_TRUE)
return 1;
- if(args->use_http) {
- http_check_enabled();
-
- klass = JS_InitClass(
- cx, global,
- NULL,
- &CouchHTTPClass, req_ctor,
- 0,
- CouchHTTPProperties, CouchHTTPFunctions,
- NULL, NULL
- );
-
- if(!klass)
- {
- fprintf(stderr, "Failed to initialize CouchHTTP class.\n");
- exit(2);
- }
- }
-
- if(args->use_test_funs) {
- if(couch_load_funcs(cx, global, TestSuiteFunctions) != JS_TRUE)
- return 1;
- }
-
for(i = 0 ; args->scripts[i] ; i++) {
// Convert script source to jschars.
scriptsrc = couch_readfile(cx, args->scripts[i]);
diff --git a/src/couch/priv/couch_js/1.8.5/util.c b/src/couch/priv/couch_js/1.8.5/util.c
index cf676ea33..5cf94b63a 100644
--- a/src/couch/priv/couch_js/1.8.5/util.c
+++ b/src/couch/priv/couch_js/1.8.5/util.c
@@ -96,8 +96,6 @@ couch_parse_args(int argc, const char* argv[])
fprintf(stderr, "Invalid stack size.\n");
exit(2);
}
- } else if(strcmp("-u", argv[i]) == 0) {
- args->uri_file = argv[++i];
} else if(strcmp("--eval", argv[i]) == 0) {
args->eval = 1;
} else if(strcmp("--", argv[i]) == 0) {
diff --git a/src/couch/priv/couch_js/1.8.5/util.h b/src/couch/priv/couch_js/1.8.5/util.h
index b24d7f76f..9dd290a4c 100644
--- a/src/couch/priv/couch_js/1.8.5/util.h
+++ b/src/couch/priv/couch_js/1.8.5/util.h
@@ -21,8 +21,6 @@ typedef struct {
int use_test_funs;
int stack_size;
const char** scripts;
- const char* uri_file;
- JSString* uri;
} couch_args;
couch_args* couch_parse_args(int argc, const char* argv[]);
diff --git a/src/couch/priv/couch_js/60/help.h b/src/couch/priv/couch_js/60/help.h
index ffb6eb40a..826babbba 100644
--- a/src/couch/priv/couch_js/60/help.h
+++ b/src/couch/priv/couch_js/60/help.h
@@ -46,15 +46,9 @@ static const char USAGE_TEMPLATE[] =
"\n"
" -h display a short help message and exit\n"
" -V display version information and exit\n"
- " -H enable %s cURL bindings (only avaiable\n"
- " if package was built with cURL available)\n"
- " -T enable test suite specific functions (these\n"
- " should not be enabled for production systems)\n"
" -S SIZE specify that the runtime should allow at\n"
" most SIZE bytes of memory to be allocated\n"
" default is 64 MiB\n"
- " -u FILE path to a .uri file containing the address\n"
- " (or addresses) of one or more servers\n"
" --eval Enable runtime code evaluation (dangerous!)\n"
"\n"
"Report bugs at <%s>.\n";
@@ -78,7 +72,6 @@ static const char USAGE_TEMPLATE[] =
basename, \
basename, \
PACKAGE_NAME, \
- basename, \
PACKAGE_BUGREPORT)
#define DISPLAY_USAGE couch_usage(BASENAME)
diff --git a/src/couch/priv/couch_js/60/http.cpp b/src/couch/priv/couch_js/60/http.cpp
deleted file mode 100644
index e1e44d622..000000000
--- a/src/couch/priv/couch_js/60/http.cpp
+++ /dev/null
@@ -1,649 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <jsapi.h>
-#include <js/Initialization.h>
-#include "config.h"
-#include "util.h"
-
-// Soft dependency on cURL bindings because they're
-// only used when running the JS tests from the
-// command line which is rare.
-#ifndef HAVE_CURL
-
-void
-http_check_enabled()
-{
- fprintf(stderr, "HTTP API was disabled at compile time.\n");
- exit(3);
-}
-
-
-bool
-http_ctor(JSContext* cx, JSObject* req)
-{
- return false;
-}
-
-
-void
-http_dtor(JSFreeOp* fop, JSObject* req)
-{
- return;
-}
-
-
-bool
-http_open(JSContext* cx, JSObject* req, JS::Value mth, JS::Value url, JS::Value snc)
-{
- return false;
-}
-
-
-bool
-http_set_hdr(JSContext* cx, JSObject* req, JS::Value name, JS::Value val)
-{
- return false;
-}
-
-
-bool
-http_send(JSContext* cx, JSObject* req, JS::Value body)
-{
- return false;
-}
-
-
-int
-http_status(JSContext* cx, JSObject* req)
-{
- return -1;
-}
-
-bool
-http_uri(JSContext* cx, JSObject* req, couch_args* args, JS::Value* uri_val)
-{
- return false;
-}
-
-
-#else
-#include <curl/curl.h>
-#ifndef XP_WIN
-#include <unistd.h>
-#endif
-
-
-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
-#endif
-
-
-typedef struct curl_slist CurlHeaders;
-
-
-typedef struct {
- int method;
- std::string url;
- CurlHeaders* req_headers;
- int16_t last_status;
-} HTTPData;
-
-
-const char* METHODS[] = {"GET", "HEAD", "POST", "PUT", "DELETE", "COPY", "OPTIONS", NULL};
-
-
-#define GET 0
-#define HEAD 1
-#define POST 2
-#define PUT 3
-#define DELETE 4
-#define COPY 5
-#define OPTIONS 6
-
-
-static bool go(JSContext* cx, JSObject* obj, HTTPData* http, std::string& body);
-
-
-bool
-http_ctor(JSContext* cx, JSObject* req)
-{
- HTTPData* http = new HTTPData();
- bool ret = false;
-
- if(!http)
- {
- JS_ReportErrorUTF8(cx, "Failed to create CouchHTTP instance.");
- goto error;
- }
-
- http->method = -1;
- http->req_headers = NULL;
- http->last_status = -1;
-
- JS_SetPrivate(req, http);
-
- ret = true;
- goto success;
-
-error:
- if(http) delete http;
-
-success:
- return ret;
-}
-
-
-void
-http_dtor(JSFreeOp* fop, JSObject* obj)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(obj);
- if(http) {
- if(http->req_headers) curl_slist_free_all(http->req_headers);
- delete http;
- }
-}
-
-
-bool
-http_open(JSContext* cx, JSObject* req, JS::Value mth, JS::Value url, JS::Value snc)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(req);
- int methid;
-
- if(!http) {
- JS_ReportErrorUTF8(cx, "Invalid CouchHTTP instance.");
- return false;
- }
-
- if(!mth.isString()) {
- JS_ReportErrorUTF8(cx, "Method must be a string.");
- return false;
- }
-
- std::string method;
- if(!js_to_string(cx, JS::RootedValue(cx, mth), method)) {
- JS_ReportErrorUTF8(cx, "Failed to encode method.");
- return false;
- }
-
- for(methid = 0; METHODS[methid] != NULL; methid++) {
- if(strcasecmp(METHODS[methid], method.c_str()) == 0) break;
- }
-
- if(methid > OPTIONS) {
- JS_ReportErrorUTF8(cx, "Invalid method specified.");
- return false;
- }
-
- http->method = methid;
-
- if(!url.isString()) {
- JS_ReportErrorUTF8(cx, "URL must be a string");
- return false;
- }
-
- std::string urlstr;
- if(!js_to_string(cx, JS::RootedValue(cx, url), urlstr)) {
- JS_ReportErrorUTF8(cx, "Failed to encode URL.");
- return false;
- }
- http->url = urlstr;
-
- if(snc.isBoolean() && snc.isTrue()) {
- JS_ReportErrorUTF8(cx, "Synchronous flag must be false.");
- return false;
- }
-
- if(http->req_headers) {
- curl_slist_free_all(http->req_headers);
- http->req_headers = NULL;
- }
-
- // Disable Expect: 100-continue
- http->req_headers = curl_slist_append(http->req_headers, "Expect:");
-
- return true;
-}
-
-
-bool
-http_set_hdr(JSContext* cx, JSObject* req, JS::Value name, JS::Value val)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(req);
-
- if(!http) {
- JS_ReportErrorUTF8(cx, "Invalid CouchHTTP instance.");
- return false;
- }
-
- if(!name.isString())
- {
- JS_ReportErrorUTF8(cx, "Header names must be strings.");
- return false;
- }
-
- std::string keystr;
- if(!js_to_string(cx, JS::RootedValue(cx, name), keystr))
- {
- JS_ReportErrorUTF8(cx, "Failed to encode header name.");
- return false;
- }
-
- if(!val.isString())
- {
- JS_ReportErrorUTF8(cx, "Header values must be strings.");
- return false;
- }
-
- std::string valstr;
- if(!js_to_string(cx, JS::RootedValue(cx, val), valstr)) {
- JS_ReportErrorUTF8(cx, "Failed to encode header value.");
- return false;
- }
-
- std::string header = keystr + ": " + valstr;
- http->req_headers = curl_slist_append(http->req_headers, header.c_str());
-
- return true;
-}
-
-bool
-http_send(JSContext* cx, JSObject* req, JS::Value body)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(req);
-
- if(!http) {
- JS_ReportErrorUTF8(cx, "Invalid CouchHTTP instance.");
- return false;
- }
-
- std::string bodystr;
- if(!js_to_string(cx, JS::RootedValue(cx, body), bodystr)) {
- JS_ReportErrorUTF8(cx, "Failed to encode body.");
- return false;
- }
-
- return go(cx, req, http, bodystr);
-}
-
-int
-http_status(JSContext* cx, JSObject* req)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(req);
-
- if(!http) {
- JS_ReportErrorUTF8(cx, "Invalid CouchHTTP instance.");
- return false;
- }
-
- return http->last_status;
-}
-
-bool
-http_uri(JSContext* cx, JSObject* req, couch_args* args, JS::Value* uri_val)
-{
- FILE* uri_fp = NULL;
- JSString* uri_str;
-
- // Default is http://localhost:15986/ when no uri file is specified
- if (!args->uri_file) {
- uri_str = JS_NewStringCopyZ(cx, "http://localhost:15986/");
- *uri_val = JS::StringValue(uri_str);
- JS_SetReservedSlot(req, 0, *uri_val);
- return true;
- }
-
- // Else check to see if the base url is cached in a reserved slot
- *uri_val = JS_GetReservedSlot(req, 0);
- if (!(*uri_val).isUndefined()) {
- return true;
- }
-
- // Read the first line of the couch.uri file.
- if(!((uri_fp = fopen(args->uri_file, "r")) &&
- (uri_str = couch_readline(cx, uri_fp)))) {
- JS_ReportErrorUTF8(cx, "Failed to read couch.uri file.");
- goto error;
- }
-
- fclose(uri_fp);
- *uri_val = JS::StringValue(uri_str);
- JS_SetReservedSlot(req, 0, *uri_val);
- return true;
-
-error:
- if(uri_fp) fclose(uri_fp);
- return false;
-}
-
-
-// Curl Helpers
-
-typedef struct {
- HTTPData* http;
- JSContext* cx;
- JSObject* resp_headers;
- const char* sendbuf;
- size_t sendlen;
- size_t sent;
- int sent_once;
- char* recvbuf;
- size_t recvlen;
- size_t read;
-} CurlState;
-
-/*
- * I really hate doing this but this doesn't have to be
- * uber awesome, it just has to work.
- */
-CURL* HTTP_HANDLE = NULL;
-char ERRBUF[CURL_ERROR_SIZE];
-
-static size_t send_body(void *ptr, size_t size, size_t nmem, void *data);
-static int seek_body(void *ptr, curl_off_t offset, int origin);
-static size_t recv_body(void *ptr, size_t size, size_t nmem, void *data);
-static size_t recv_header(void *ptr, size_t size, size_t nmem, void *data);
-
-static bool
-go(JSContext* cx, JSObject* obj, HTTPData* http, std::string& body)
-{
- CurlState state;
- JSString* jsbody;
- bool ret = false;
- JS::Value tmp;
- JS::RootedObject robj(cx, obj);
- JS::RootedValue vobj(cx);
-
-
- state.cx = cx;
- state.http = http;
-
- state.sendbuf = body.c_str();
- state.sendlen = body.size();
- state.sent = 0;
- state.sent_once = 0;
-
- state.recvbuf = NULL;
- state.recvlen = 0;
- state.read = 0;
-
- 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,
- (curl_seek_callback) seek_body);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_HEADERFUNCTION, recv_header);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEFUNCTION, recv_body);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOPROGRESS, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_ERRORBUFFER, ERRBUF);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_COOKIEFILE, "");
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_USERAGENT,
- "CouchHTTP Client - Relax");
- }
-
- if(!HTTP_HANDLE) {
- JS_ReportErrorUTF8(cx, "Failed to initialize cURL handle.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
-
- tmp = JS_GetReservedSlot(obj, 0);
-
- std::string referer;
- if(!js_to_string(cx, JS::RootedValue(cx, tmp), referer)) {
- JS_ReportErrorUTF8(cx, "Failed to encode referer.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_REFERER, referer.c_str());
-
- if(http->method < 0 || http->method > OPTIONS) {
- JS_ReportErrorUTF8(cx, "INTERNAL: Unknown method.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
-
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_CUSTOMREQUEST, METHODS[http->method]);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOBODY, 0);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 0);
-
- 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) {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 0);
- }
-
- if(body.size() > 0) {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, body.size());
- } else {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, 0);
- }
-
- // curl_easy_setopt(HTTP_HANDLE, CURLOPT_VERBOSE, 1);
-
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_URL, http->url.c_str());
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_HTTPHEADER, http->req_headers);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_READDATA, &state);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_SEEKDATA, &state);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEHEADER, &state);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEDATA, &state);
-
- if(curl_easy_perform(HTTP_HANDLE) != 0) {
- JS_ReportErrorUTF8(cx, "Failed to execute HTTP request: %s", ERRBUF);
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
-
- if(!state.resp_headers) {
- JS_ReportErrorUTF8(cx, "Failed to recieve HTTP headers.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
- tmp = JS::ObjectValue(*state.resp_headers);
- JS::RootedValue rtmp(cx, tmp);
-
- if(!JS_DefineProperty(
- cx, robj,
- "_headers",
- rtmp,
- JSPROP_READONLY
- )) {
- JS_ReportErrorUTF8(cx, "INTERNAL: Failed to set response headers.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;;
- }
-
- if(state.recvbuf) {
- state.recvbuf[state.read] = '\0';
- std::string bodystr(state.recvbuf, state.read);
- jsbody = string_to_js(cx, bodystr);
- 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 char16_t.
- jsbody = JS_NewStringCopyN(cx, state.recvbuf, state.read);
- if(!jsbody) {
- if(!JS_IsExceptionPending(cx)) {
- JS_ReportErrorUTF8(cx, "INTERNAL: Failed to decode body.");
- }
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
- }
- tmp = JS::StringValue(jsbody);
- } else {
- tmp = JS_GetEmptyStringValue(cx);
- }
-
- JS::RootedValue rtmp2(cx, tmp);
-
- if(!JS_DefineProperty(
- cx, robj,
- "responseText",
- rtmp2,
- JSPROP_READONLY
- )) {
- JS_ReportErrorUTF8(cx, "INTERNAL: Failed to set responseText.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
-
- ret = true;
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
-}
-
-static size_t
-send_body(void *ptr, size_t size, size_t nmem, void *data)
-{
- CurlState* state = static_cast<CurlState*>(data);
- size_t length = size * nmem;
- size_t towrite = state->sendlen - state->sent;
-
- // 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;
-
- memcpy(ptr, state->sendbuf + state->sent, towrite);
- state->sent += towrite;
-
- return towrite;
-}
-
-static int
-seek_body(void* ptr, curl_off_t offset, int origin)
-{
- CurlState* state = static_cast<CurlState*>(ptr);
- if(origin != SEEK_SET) return -1;
-
- state->sent = static_cast<size_t>(offset);
- return static_cast<int>(state->sent);
-}
-
-static size_t
-recv_header(void *ptr, size_t size, size_t nmem, void *data)
-{
- CurlState* state = static_cast<CurlState*>(data);
- char code[4];
- char* header = static_cast<char*>(ptr);
- size_t length = size * nmem;
- JSString* hdr = NULL;
- uint32_t hdrlen;
-
- if(length > 7 && strncasecmp(header, "HTTP/1.", 7) == 0) {
- if(length < 12) {
- return CURLE_WRITE_ERROR;
- }
-
- memcpy(code, header+9, 3*sizeof(char));
- code[3] = '\0';
- state->http->last_status = atoi(code);
-
- state->resp_headers = JS_NewArrayObject(state->cx, 0);
- if(!state->resp_headers) {
- return CURLE_WRITE_ERROR;
- }
-
- return length;
- }
-
- // We get a notice at the \r\n\r\n after headers.
- if(length <= 2) {
- return length;
- }
-
- // Append the new header to our array.
- std::string hdrstr(header, length);
- hdr = string_to_js(state->cx, hdrstr);
- if(!hdr) {
- return CURLE_WRITE_ERROR;
- }
-
- JS::RootedObject obj(state->cx, state->resp_headers);
- if(!JS_GetArrayLength(state->cx, obj, &hdrlen)) {
- return CURLE_WRITE_ERROR;
- }
-
- JS::RootedString hdrval(state->cx, hdr);
- if(!JS_SetElement(state->cx, obj, hdrlen, hdrval)) {
- return CURLE_WRITE_ERROR;
- }
-
- return length;
-}
-
-static size_t
-recv_body(void *ptr, size_t size, size_t nmem, void *data)
-{
- CurlState* state = static_cast<CurlState*>(data);
- size_t length = size * nmem;
- char* tmp = NULL;
-
- if(!state->recvbuf) {
- state->recvlen = 4096;
- state->read = 0;
- state->recvbuf = static_cast<char*>(JS_malloc(
- state->cx,
- state->recvlen
- ));
- }
-
- if(!state->recvbuf) {
- return CURLE_WRITE_ERROR;
- }
-
- // +1 so we can add '\0' back up in the go function.
- size_t oldlen = state->recvlen;
- while(length+1 > state->recvlen - state->read) state->recvlen *= 2;
- tmp = static_cast<char*>(JS_realloc(
- state->cx,
- state->recvbuf,
- oldlen,
- state->recvlen
- ));
- if(!tmp) return CURLE_WRITE_ERROR;
- state->recvbuf = tmp;
-
- memcpy(state->recvbuf + state->read, ptr, length);
- state->read += length;
- return length;
-}
-
-#endif /* HAVE_CURL */
diff --git a/src/couch/priv/couch_js/60/http.h b/src/couch/priv/couch_js/60/http.h
deleted file mode 100644
index 797b3c060..000000000
--- a/src/couch/priv/couch_js/60/http.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-#ifndef COUCH_JS_HTTP_H
-#define COUCH_JS_HTTP_H
-
-#include "util.h"
-
-void http_check_enabled();
-bool http_ctor(JSContext* cx, JSObject* req);
-void http_dtor(JSFreeOp* fop, JSObject* req);
-bool http_open(JSContext* cx, JSObject* req, JS::Value mth, JS::Value url, JS::Value snc);
-bool http_set_hdr(JSContext* cx, JSObject* req, JS::Value name, JS::Value val);
-bool http_send(JSContext* cx, JSObject* req, JS::Value body);
-int http_status(JSContext* cx, JSObject* req);
-bool http_uri(JSContext* cx, JSObject *req, couch_args* args, JS::Value* uri);
-
-#endif
diff --git a/src/couch/priv/couch_js/60/main.cpp b/src/couch/priv/couch_js/60/main.cpp
index 828b9dab5..5169b05d7 100644
--- a/src/couch/priv/couch_js/60/main.cpp
+++ b/src/couch/priv/couch_js/60/main.cpp
@@ -27,7 +27,6 @@
#include <js/Wrapper.h>
#include "config.h"
-#include "http.h"
#include "util.h"
static bool enableSharedMemory = true;
@@ -53,136 +52,6 @@ static JSClass global_class = {
&global_ops
};
-
-static void
-req_dtor(JSFreeOp* fop, JSObject* obj)
-{
- http_dtor(fop, obj);
-}
-
-// With JSClass.construct.
-static const JSClassOps clsOps = {
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- req_dtor,
- nullptr,
- nullptr,
- nullptr
-};
-
-static const JSClass CouchHTTPClass = {
- "CouchHTTP", /* name */
- JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(2), /* flags */
- &clsOps
-};
-
-static bool
-req_ctor(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- bool ret;
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JSObject* obj = JS_NewObjectForConstructor(cx, &CouchHTTPClass, args);
- if(!obj) {
- JS_ReportErrorUTF8(cx, "Failed to create CouchHTTP instance");
- return false;
- }
- ret = http_ctor(cx, obj);
- args.rval().setObject(*obj);
- return ret;
-}
-
-static bool
-req_open(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JS::Value vobj = args.computeThis(cx);
- JSObject* obj = vobj.toObjectOrNull();
- bool ret = false;
-
- if(argc == 2) {
- ret = http_open(cx, obj, args[0], args[1], JS::BooleanValue(false));
- } else if(argc == 3) {
- ret = http_open(cx, obj, args[0], args[1], args[2]);
- } else {
- JS_ReportErrorUTF8(cx, "Invalid call to CouchHTTP.open");
- }
-
- args.rval().setUndefined();
- return ret;
-}
-
-
-static bool
-req_set_hdr(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JS::Value vobj = args.computeThis(cx);
- JSObject* obj = vobj.toObjectOrNull();
- bool ret = false;
-
- if(argc == 2) {
- ret = http_set_hdr(cx, obj, args[0], args[1]);
- } else {
- JS_ReportErrorUTF8(cx, "Invalid call to CouchHTTP.set_header");
- }
-
- args.rval().setUndefined();
- return ret;
-}
-
-
-static bool
-req_send(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JS::Value vobj = args.computeThis(cx);
- JSObject* obj = vobj.toObjectOrNull();
- bool ret = false;
-
- if(argc == 1) {
- ret = http_send(cx, obj, args[0]);
- } else {
- JS_ReportErrorUTF8(cx, "Invalid call to CouchHTTP.send");
- }
-
- args.rval().setUndefined();
- return ret;
-}
-
-static bool
-req_status(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JS::Value vobj = args.computeThis(cx);
- JSObject* obj = vobj.toObjectOrNull();
-
- int status = http_status(cx, obj);
-
- if(status < 0)
- return false;
-
- args.rval().set(JS::Int32Value(status));
- return true;
-}
-
-static bool
-base_url(JSContext *cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JS::Value vobj = args.computeThis(cx);
- JSObject* obj = vobj.toObjectOrNull();
-
- couch_args *cargs = static_cast<couch_args*>(JS_GetContextPrivate(cx));
- JS::Value uri_val;
- bool rc = http_uri(cx, obj, cargs, &uri_val);
- args.rval().set(uri_val);
- return rc;
-}
-
static void
SetStandardCompartmentOptions(JS::CompartmentOptions& options)
{
@@ -353,43 +222,6 @@ seal(JSContext* cx, unsigned int argc, JS::Value* vp)
}
-static bool
-js_sleep(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
-
- int duration = args[0].toInt32();
-
-#ifdef XP_WIN
- Sleep(duration);
-#else
- usleep(duration * 1000);
-#endif
-
- return true;
-}
-
-JSPropertySpec CouchHTTPProperties[] = {
- JS_PSG("status", req_status, 0),
- JS_PSG("base_url", base_url, 0),
- JS_PS_END
-};
-
-
-JSFunctionSpec CouchHTTPFunctions[] = {
- JS_FN("_open", req_open, 3, 0),
- JS_FN("_setRequestHeader", req_set_hdr, 2, 0),
- JS_FN("_send", req_send, 1, 0),
- JS_FS_END
-};
-
-
-JSFunctionSpec TestSuiteFunctions[] = {
- JS_FN("sleep", js_sleep, 1, 0),
- JS_FS_END
-};
-
-
static JSFunctionSpec global_functions[] = {
JS_FN("evalcx", evalcx, 0, 0),
JS_FN("gc", gc, 0, 0),
@@ -423,7 +255,6 @@ int
main(int argc, const char* argv[])
{
JSContext* cx = NULL;
- JSObject* klass = NULL;
char* scriptsrc;
size_t slen;
int i;
@@ -461,30 +292,6 @@ main(int argc, const char* argv[])
if(couch_load_funcs(cx, global, global_functions) != true)
return 1;
- if(args->use_http) {
- http_check_enabled();
-
- klass = JS_InitClass(
- cx, global,
- NULL,
- &CouchHTTPClass, req_ctor,
- 0,
- CouchHTTPProperties, CouchHTTPFunctions,
- NULL, NULL
- );
-
- if(!klass)
- {
- fprintf(stderr, "Failed to initialize CouchHTTP class.\n");
- exit(2);
- }
- }
-
- if(args->use_test_funs) {
- if(couch_load_funcs(cx, global, TestSuiteFunctions) != true)
- return 1;
- }
-
for(i = 0 ; args->scripts[i] ; i++) {
slen = couch_readfile(args->scripts[i], &scriptsrc);
diff --git a/src/couch/priv/couch_js/60/util.cpp b/src/couch/priv/couch_js/60/util.cpp
index c37c41f2f..3bc58a921 100644
--- a/src/couch/priv/couch_js/60/util.cpp
+++ b/src/couch/priv/couch_js/60/util.cpp
@@ -142,12 +142,8 @@ couch_parse_args(int argc, const char* argv[])
return NULL;
args->eval = 0;
- args->use_http = 0;
- args->use_test_funs = 0;
args->stack_size = 64L * 1024L * 1024L;
args->scripts = nullptr;
- args->uri_file = nullptr;
- args->uri = nullptr;
while(i < argc) {
if(strcmp("-h", argv[i]) == 0) {
@@ -156,18 +152,12 @@ couch_parse_args(int argc, const char* argv[])
} else if(strcmp("-V", argv[i]) == 0) {
DISPLAY_VERSION;
exit(0);
- } else if(strcmp("-H", argv[i]) == 0) {
- args->use_http = 1;
- } else if(strcmp("-T", argv[i]) == 0) {
- args->use_test_funs = 1;
} else if(strcmp("-S", argv[i]) == 0) {
args->stack_size = atoi(argv[++i]);
if(args->stack_size <= 0) {
fprintf(stderr, "Invalid stack size.\n");
exit(2);
}
- } else if(strcmp("-u", argv[i]) == 0) {
- args->uri_file = argv[++i];
} else if(strcmp("--eval", argv[i]) == 0) {
args->eval = 1;
} else if(strcmp("--", argv[i]) == 0) {
diff --git a/src/couch/priv/couch_js/60/util.h b/src/couch/priv/couch_js/60/util.h
index 4c27f0f66..35882a614 100644
--- a/src/couch/priv/couch_js/60/util.h
+++ b/src/couch/priv/couch_js/60/util.h
@@ -17,12 +17,8 @@
typedef struct {
int eval;
- int use_http;
- int use_test_funs;
int stack_size;
const char** scripts;
- const char* uri_file;
- JSString* uri;
} couch_args;
std::string js_to_string(JSContext* cx, JS::HandleValue val);
diff --git a/src/couch/priv/couch_js/68/help.h b/src/couch/priv/couch_js/68/help.h
index c5cb83285..7c7550cc2 100644
--- a/src/couch/priv/couch_js/68/help.h
+++ b/src/couch/priv/couch_js/68/help.h
@@ -46,15 +46,9 @@ static const char USAGE_TEMPLATE[] =
"\n"
" -h display a short help message and exit\n"
" -V display version information and exit\n"
- " -H enable %s cURL bindings (only avaiable\n"
- " if package was built with cURL available)\n"
- " -T enable test suite specific functions (these\n"
- " should not be enabled for production systems)\n"
" -S SIZE specify that the runtime should allow at\n"
" most SIZE bytes of memory to be allocated\n"
" default is 64 MiB\n"
- " -u FILE path to a .uri file containing the address\n"
- " (or addresses) of one or more servers\n"
" --eval Enable runtime code evaluation (dangerous!)\n"
"\n"
"Report bugs at <%s>.\n";
@@ -78,7 +72,6 @@ static const char USAGE_TEMPLATE[] =
basename, \
basename, \
PACKAGE_NAME, \
- basename, \
PACKAGE_BUGREPORT)
#define DISPLAY_USAGE couch_usage(BASENAME)
diff --git a/src/couch/priv/couch_js/68/http.cpp b/src/couch/priv/couch_js/68/http.cpp
deleted file mode 100644
index 20a609701..000000000
--- a/src/couch/priv/couch_js/68/http.cpp
+++ /dev/null
@@ -1,650 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <jsapi.h>
-#include <js/Initialization.h>
-#include <js/MemoryFunctions.h>
-#include "config.h"
-#include "util.h"
-
-// Soft dependency on cURL bindings because they're
-// only used when running the JS tests from the
-// command line which is rare.
-#ifndef HAVE_CURL
-
-void
-http_check_enabled()
-{
- fprintf(stderr, "HTTP API was disabled at compile time.\n");
- exit(3);
-}
-
-
-bool
-http_ctor(JSContext* cx, JSObject* req)
-{
- return false;
-}
-
-
-void
-http_dtor(JSFreeOp* fop, JSObject* req)
-{
- return;
-}
-
-
-bool
-http_open(JSContext* cx, JSObject* req, JS::Value mth, JS::Value url, JS::Value snc)
-{
- return false;
-}
-
-
-bool
-http_set_hdr(JSContext* cx, JSObject* req, JS::Value name, JS::Value val)
-{
- return false;
-}
-
-
-bool
-http_send(JSContext* cx, JSObject* req, JS::Value body)
-{
- return false;
-}
-
-
-int
-http_status(JSContext* cx, JSObject* req)
-{
- return -1;
-}
-
-bool
-http_uri(JSContext* cx, JSObject* req, couch_args* args, JS::Value* uri_val)
-{
- return false;
-}
-
-
-#else
-#include <curl/curl.h>
-#ifndef XP_WIN
-#include <unistd.h>
-#endif
-
-
-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
-#endif
-
-
-typedef struct curl_slist CurlHeaders;
-
-
-typedef struct {
- int method;
- std::string url;
- CurlHeaders* req_headers;
- int16_t last_status;
-} HTTPData;
-
-
-const char* METHODS[] = {"GET", "HEAD", "POST", "PUT", "DELETE", "COPY", "OPTIONS", NULL};
-
-
-#define GET 0
-#define HEAD 1
-#define POST 2
-#define PUT 3
-#define DELETE 4
-#define COPY 5
-#define OPTIONS 6
-
-
-static bool go(JSContext* cx, JSObject* obj, HTTPData* http, std::string& body);
-
-
-bool
-http_ctor(JSContext* cx, JSObject* req)
-{
- HTTPData* http = new HTTPData();
- bool ret = false;
-
- if(!http)
- {
- JS_ReportErrorUTF8(cx, "Failed to create CouchHTTP instance.");
- goto error;
- }
-
- http->method = -1;
- http->req_headers = NULL;
- http->last_status = -1;
-
- JS_SetPrivate(req, http);
-
- ret = true;
- goto success;
-
-error:
- if(http) delete http;
-
-success:
- return ret;
-}
-
-
-void
-http_dtor(JSFreeOp* fop, JSObject* obj)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(obj);
- if(http) {
- if(http->req_headers) curl_slist_free_all(http->req_headers);
- delete http;
- }
-}
-
-
-bool
-http_open(JSContext* cx, JSObject* req, JS::Value mth, JS::Value url, JS::Value snc)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(req);
- int methid;
-
- if(!http) {
- JS_ReportErrorUTF8(cx, "Invalid CouchHTTP instance.");
- return false;
- }
-
- if(!mth.isString()) {
- JS_ReportErrorUTF8(cx, "Method must be a string.");
- return false;
- }
-
- std::string method;
- if(!js_to_string(cx, JS::RootedValue(cx, mth), method)) {
- JS_ReportErrorUTF8(cx, "Failed to encode method.");
- return false;
- }
-
- for(methid = 0; METHODS[methid] != NULL; methid++) {
- if(strcasecmp(METHODS[methid], method.c_str()) == 0) break;
- }
-
- if(methid > OPTIONS) {
- JS_ReportErrorUTF8(cx, "Invalid method specified.");
- return false;
- }
-
- http->method = methid;
-
- if(!url.isString()) {
- JS_ReportErrorUTF8(cx, "URL must be a string");
- return false;
- }
-
- std::string urlstr;
- if(!js_to_string(cx, JS::RootedValue(cx, url), urlstr)) {
- JS_ReportErrorUTF8(cx, "Failed to encode URL.");
- return false;
- }
- http->url = urlstr;
-
- if(snc.isBoolean() && snc.isTrue()) {
- JS_ReportErrorUTF8(cx, "Synchronous flag must be false.");
- return false;
- }
-
- if(http->req_headers) {
- curl_slist_free_all(http->req_headers);
- http->req_headers = NULL;
- }
-
- // Disable Expect: 100-continue
- http->req_headers = curl_slist_append(http->req_headers, "Expect:");
-
- return true;
-}
-
-
-bool
-http_set_hdr(JSContext* cx, JSObject* req, JS::Value name, JS::Value val)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(req);
-
- if(!http) {
- JS_ReportErrorUTF8(cx, "Invalid CouchHTTP instance.");
- return false;
- }
-
- if(!name.isString())
- {
- JS_ReportErrorUTF8(cx, "Header names must be strings.");
- return false;
- }
-
- std::string keystr;
- if(!js_to_string(cx, JS::RootedValue(cx, name), keystr))
- {
- JS_ReportErrorUTF8(cx, "Failed to encode header name.");
- return false;
- }
-
- if(!val.isString())
- {
- JS_ReportErrorUTF8(cx, "Header values must be strings.");
- return false;
- }
-
- std::string valstr;
- if(!js_to_string(cx, JS::RootedValue(cx, val), valstr)) {
- JS_ReportErrorUTF8(cx, "Failed to encode header value.");
- return false;
- }
-
- std::string header = keystr + ": " + valstr;
- http->req_headers = curl_slist_append(http->req_headers, header.c_str());
-
- return true;
-}
-
-bool
-http_send(JSContext* cx, JSObject* req, JS::Value body)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(req);
-
- if(!http) {
- JS_ReportErrorUTF8(cx, "Invalid CouchHTTP instance.");
- return false;
- }
-
- std::string bodystr;
- if(!js_to_string(cx, JS::RootedValue(cx, body), bodystr)) {
- JS_ReportErrorUTF8(cx, "Failed to encode body.");
- return false;
- }
-
- return go(cx, req, http, bodystr);
-}
-
-int
-http_status(JSContext* cx, JSObject* req)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(req);
-
- if(!http) {
- JS_ReportErrorUTF8(cx, "Invalid CouchHTTP instance.");
- return false;
- }
-
- return http->last_status;
-}
-
-bool
-http_uri(JSContext* cx, JSObject* req, couch_args* args, JS::Value* uri_val)
-{
- FILE* uri_fp = NULL;
- JSString* uri_str;
-
- // Default is http://localhost:15986/ when no uri file is specified
- if (!args->uri_file) {
- uri_str = JS_NewStringCopyZ(cx, "http://localhost:15986/");
- *uri_val = JS::StringValue(uri_str);
- JS_SetReservedSlot(req, 0, *uri_val);
- return true;
- }
-
- // Else check to see if the base url is cached in a reserved slot
- *uri_val = JS_GetReservedSlot(req, 0);
- if (!(*uri_val).isUndefined()) {
- return true;
- }
-
- // Read the first line of the couch.uri file.
- if(!((uri_fp = fopen(args->uri_file, "r")) &&
- (uri_str = couch_readline(cx, uri_fp)))) {
- JS_ReportErrorUTF8(cx, "Failed to read couch.uri file.");
- goto error;
- }
-
- fclose(uri_fp);
- *uri_val = JS::StringValue(uri_str);
- JS_SetReservedSlot(req, 0, *uri_val);
- return true;
-
-error:
- if(uri_fp) fclose(uri_fp);
- return false;
-}
-
-
-// Curl Helpers
-
-typedef struct {
- HTTPData* http;
- JSContext* cx;
- JSObject* resp_headers;
- const char* sendbuf;
- size_t sendlen;
- size_t sent;
- int sent_once;
- char* recvbuf;
- size_t recvlen;
- size_t read;
-} CurlState;
-
-/*
- * I really hate doing this but this doesn't have to be
- * uber awesome, it just has to work.
- */
-CURL* HTTP_HANDLE = NULL;
-char ERRBUF[CURL_ERROR_SIZE];
-
-static size_t send_body(void *ptr, size_t size, size_t nmem, void *data);
-static int seek_body(void *ptr, curl_off_t offset, int origin);
-static size_t recv_body(void *ptr, size_t size, size_t nmem, void *data);
-static size_t recv_header(void *ptr, size_t size, size_t nmem, void *data);
-
-static bool
-go(JSContext* cx, JSObject* obj, HTTPData* http, std::string& body)
-{
- CurlState state;
- JSString* jsbody;
- bool ret = false;
- JS::Value tmp;
- JS::RootedObject robj(cx, obj);
- JS::RootedValue vobj(cx);
-
-
- state.cx = cx;
- state.http = http;
-
- state.sendbuf = body.c_str();;
- state.sendlen = body.size();
- state.sent = 0;
- state.sent_once = 0;
-
- state.recvbuf = NULL;
- state.recvlen = 0;
- state.read = 0;
-
- 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,
- (curl_seek_callback) seek_body);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_HEADERFUNCTION, recv_header);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEFUNCTION, recv_body);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOPROGRESS, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_ERRORBUFFER, ERRBUF);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_COOKIEFILE, "");
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_USERAGENT,
- "CouchHTTP Client - Relax");
- }
-
- if(!HTTP_HANDLE) {
- JS_ReportErrorUTF8(cx, "Failed to initialize cURL handle.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
-
- tmp = JS_GetReservedSlot(obj, 0);
-
- std::string referer;
- if(!js_to_string(cx, JS::RootedValue(cx, tmp), referer)) {
- JS_ReportErrorUTF8(cx, "Failed to encode referer.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_REFERER, referer.c_str());
-
- if(http->method < 0 || http->method > OPTIONS) {
- JS_ReportErrorUTF8(cx, "INTERNAL: Unknown method.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
-
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_CUSTOMREQUEST, METHODS[http->method]);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOBODY, 0);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 0);
-
- 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) {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 0);
- }
-
- if(body.size() > 0) {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, body.size());
- } else {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, 0);
- }
-
- // curl_easy_setopt(HTTP_HANDLE, CURLOPT_VERBOSE, 1);
-
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_URL, http->url.c_str());
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_HTTPHEADER, http->req_headers);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_READDATA, &state);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_SEEKDATA, &state);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEHEADER, &state);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEDATA, &state);
-
- if(curl_easy_perform(HTTP_HANDLE) != 0) {
- JS_ReportErrorUTF8(cx, "Failed to execute HTTP request: %s", ERRBUF);
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
-
- if(!state.resp_headers) {
- JS_ReportErrorUTF8(cx, "Failed to recieve HTTP headers.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
- tmp = JS::ObjectValue(*state.resp_headers);
- JS::RootedValue rtmp(cx, tmp);
-
- if(!JS_DefineProperty(
- cx, robj,
- "_headers",
- rtmp,
- JSPROP_READONLY
- )) {
- JS_ReportErrorUTF8(cx, "INTERNAL: Failed to set response headers.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;;
- }
-
- if(state.recvbuf) {
- state.recvbuf[state.read] = '\0';
- std::string bodystr(state.recvbuf, state.read);
- jsbody = string_to_js(cx, bodystr);
- 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 char16_t.
- jsbody = JS_NewStringCopyN(cx, state.recvbuf, state.read);
- if(!jsbody) {
- if(!JS_IsExceptionPending(cx)) {
- JS_ReportErrorUTF8(cx, "INTERNAL: Failed to decode body.");
- }
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
- }
- tmp = JS::StringValue(jsbody);
- } else {
- tmp = JS_GetEmptyStringValue(cx);
- }
-
- JS::RootedValue rtmp2(cx, tmp);
-
- if(!JS_DefineProperty(
- cx, robj,
- "responseText",
- rtmp2,
- JSPROP_READONLY
- )) {
- JS_ReportErrorUTF8(cx, "INTERNAL: Failed to set responseText.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
-
- ret = true;
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
-}
-
-static size_t
-send_body(void *ptr, size_t size, size_t nmem, void *data)
-{
- CurlState* state = static_cast<CurlState*>(data);
- size_t length = size * nmem;
- size_t towrite = state->sendlen - state->sent;
-
- // 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;
-
- memcpy(ptr, state->sendbuf + state->sent, towrite);
- state->sent += towrite;
-
- return towrite;
-}
-
-static int
-seek_body(void* ptr, curl_off_t offset, int origin)
-{
- CurlState* state = static_cast<CurlState*>(ptr);
- if(origin != SEEK_SET) return -1;
-
- state->sent = static_cast<size_t>(offset);
- return static_cast<int>(state->sent);
-}
-
-static size_t
-recv_header(void *ptr, size_t size, size_t nmem, void *data)
-{
- CurlState* state = static_cast<CurlState*>(data);
- char code[4];
- char* header = static_cast<char*>(ptr);
- size_t length = size * nmem;
- JSString* hdr = NULL;
- uint32_t hdrlen;
-
- if(length > 7 && strncasecmp(header, "HTTP/1.", 7) == 0) {
- if(length < 12) {
- return CURLE_WRITE_ERROR;
- }
-
- memcpy(code, header+9, 3*sizeof(char));
- code[3] = '\0';
- state->http->last_status = atoi(code);
-
- state->resp_headers = JS_NewArrayObject(state->cx, 0);
- if(!state->resp_headers) {
- return CURLE_WRITE_ERROR;
- }
-
- return length;
- }
-
- // We get a notice at the \r\n\r\n after headers.
- if(length <= 2) {
- return length;
- }
-
- // Append the new header to our array.
- std::string hdrstr(header, length);
- hdr = string_to_js(state->cx, hdrstr);
- if(!hdr) {
- return CURLE_WRITE_ERROR;
- }
-
- JS::RootedObject obj(state->cx, state->resp_headers);
- if(!JS_GetArrayLength(state->cx, obj, &hdrlen)) {
- return CURLE_WRITE_ERROR;
- }
-
- JS::RootedString hdrval(state->cx, hdr);
- if(!JS_SetElement(state->cx, obj, hdrlen, hdrval)) {
- return CURLE_WRITE_ERROR;
- }
-
- return length;
-}
-
-static size_t
-recv_body(void *ptr, size_t size, size_t nmem, void *data)
-{
- CurlState* state = static_cast<CurlState*>(data);
- size_t length = size * nmem;
- char* tmp = NULL;
-
- if(!state->recvbuf) {
- state->recvlen = 4096;
- state->read = 0;
- state->recvbuf = static_cast<char*>(JS_malloc(
- state->cx,
- state->recvlen
- ));
- }
-
- if(!state->recvbuf) {
- return CURLE_WRITE_ERROR;
- }
-
- // +1 so we can add '\0' back up in the go function.
- size_t oldlen = state->recvlen;
- while(length+1 > state->recvlen - state->read) state->recvlen *= 2;
- tmp = static_cast<char*>(JS_realloc(
- state->cx,
- state->recvbuf,
- oldlen,
- state->recvlen
- ));
- if(!tmp) return CURLE_WRITE_ERROR;
- state->recvbuf = tmp;
-
- memcpy(state->recvbuf + state->read, ptr, length);
- state->read += length;
- return length;
-}
-
-#endif /* HAVE_CURL */
diff --git a/src/couch/priv/couch_js/68/http.h b/src/couch/priv/couch_js/68/http.h
deleted file mode 100644
index 797b3c060..000000000
--- a/src/couch/priv/couch_js/68/http.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-#ifndef COUCH_JS_HTTP_H
-#define COUCH_JS_HTTP_H
-
-#include "util.h"
-
-void http_check_enabled();
-bool http_ctor(JSContext* cx, JSObject* req);
-void http_dtor(JSFreeOp* fop, JSObject* req);
-bool http_open(JSContext* cx, JSObject* req, JS::Value mth, JS::Value url, JS::Value snc);
-bool http_set_hdr(JSContext* cx, JSObject* req, JS::Value name, JS::Value val);
-bool http_send(JSContext* cx, JSObject* req, JS::Value body);
-int http_status(JSContext* cx, JSObject* req);
-bool http_uri(JSContext* cx, JSObject *req, couch_args* args, JS::Value* uri);
-
-#endif
diff --git a/src/couch/priv/couch_js/68/main.cpp b/src/couch/priv/couch_js/68/main.cpp
index 2c95f6129..bb62d16ca 100644
--- a/src/couch/priv/couch_js/68/main.cpp
+++ b/src/couch/priv/couch_js/68/main.cpp
@@ -30,7 +30,6 @@
#include <js/Wrapper.h>
#include "config.h"
-#include "http.h"
#include "util.h"
static bool enableSharedMemory = true;
@@ -56,141 +55,6 @@ static JSClass global_class = {
&global_ops
};
-
-static void
-req_dtor(JSFreeOp* fop, JSObject* obj)
-{
- http_dtor(fop, obj);
-}
-
-// With JSClass.construct.
-static const JSClassOps clsOps = {
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- req_dtor,
- nullptr,
- nullptr,
- nullptr
-};
-
-static const JSClass CouchHTTPClass = {
- "CouchHTTP", /* name */
- JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(2), /* flags */
- &clsOps
-};
-
-static bool
-req_ctor(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- bool ret;
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JSObject* obj = JS_NewObjectForConstructor(cx, &CouchHTTPClass, args);
- if(!obj) {
- JS_ReportErrorUTF8(cx, "Failed to create CouchHTTP instance");
- return false;
- }
- ret = http_ctor(cx, obj);
- args.rval().setObject(*obj);
- return ret;
-}
-
-static bool
-req_open(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JS::RootedObject obj(cx);
- if (!args.computeThis(cx, &obj))
- return false;
- bool ret = false;
-
- if(argc == 2) {
- ret = http_open(cx, obj, args[0], args[1], JS::BooleanValue(false));
- } else if(argc == 3) {
- ret = http_open(cx, obj, args[0], args[1], args[2]);
- } else {
- JS_ReportErrorUTF8(cx, "Invalid call to CouchHTTP.open");
- }
-
- args.rval().setUndefined();
- return ret;
-}
-
-
-static bool
-req_set_hdr(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JS::RootedObject obj(cx);
- if (!args.computeThis(cx, &obj))
- return false;
- bool ret = false;
-
- if(argc == 2) {
- ret = http_set_hdr(cx, obj, args[0], args[1]);
- } else {
- JS_ReportErrorUTF8(cx, "Invalid call to CouchHTTP.set_header");
- }
-
- args.rval().setUndefined();
- return ret;
-}
-
-
-static bool
-req_send(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JS::RootedObject obj(cx);
- if (!args.computeThis(cx, &obj))
- return false;
- bool ret = false;
-
- if(argc == 1) {
- ret = http_send(cx, obj, args[0]);
- } else {
- JS_ReportErrorUTF8(cx, "Invalid call to CouchHTTP.send");
- }
-
- args.rval().setUndefined();
- return ret;
-}
-
-static bool
-req_status(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JS::RootedObject obj(cx);
- if (!args.computeThis(cx, &obj))
- return false;
-
- int status = http_status(cx, obj);
-
- if(status < 0)
- return false;
-
- args.rval().set(JS::Int32Value(status));
- return true;
-}
-
-static bool
-base_url(JSContext *cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JS::RootedObject obj(cx);
- if (!args.computeThis(cx, &obj))
- return false;
-
- couch_args *cargs = static_cast<couch_args*>(JS_GetContextPrivate(cx));
- JS::Value uri_val;
- bool rc = http_uri(cx, obj, cargs, &uri_val);
- args.rval().set(uri_val);
- return rc;
-}
-
static JSObject*
NewSandbox(JSContext* cx, bool lazy)
{
@@ -358,43 +222,6 @@ seal(JSContext* cx, unsigned int argc, JS::Value* vp)
}
-static bool
-js_sleep(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
-
- int duration = args[0].toInt32();
-
-#ifdef XP_WIN
- Sleep(duration);
-#else
- usleep(duration * 1000);
-#endif
-
- return true;
-}
-
-JSPropertySpec CouchHTTPProperties[] = {
- JS_PSG("status", req_status, 0),
- JS_PSG("base_url", base_url, 0),
- JS_PS_END
-};
-
-
-JSFunctionSpec CouchHTTPFunctions[] = {
- JS_FN("_open", req_open, 3, 0),
- JS_FN("_setRequestHeader", req_set_hdr, 2, 0),
- JS_FN("_send", req_send, 1, 0),
- JS_FS_END
-};
-
-
-JSFunctionSpec TestSuiteFunctions[] = {
- JS_FN("sleep", js_sleep, 1, 0),
- JS_FS_END
-};
-
-
static JSFunctionSpec global_functions[] = {
JS_FN("evalcx", evalcx, 0, 0),
JS_FN("gc", gc, 0, 0),
@@ -428,7 +255,6 @@ int
main(int argc, const char* argv[])
{
JSContext* cx = NULL;
- JSObject* klass = NULL;
int i;
couch_args* args = couch_parse_args(argc, argv);
@@ -463,30 +289,6 @@ main(int argc, const char* argv[])
if(couch_load_funcs(cx, global, global_functions) != true)
return 1;
- if(args->use_http) {
- http_check_enabled();
-
- klass = JS_InitClass(
- cx, global,
- NULL,
- &CouchHTTPClass, req_ctor,
- 0,
- CouchHTTPProperties, CouchHTTPFunctions,
- NULL, NULL
- );
-
- if(!klass)
- {
- fprintf(stderr, "Failed to initialize CouchHTTP class.\n");
- exit(2);
- }
- }
-
- if(args->use_test_funs) {
- if(couch_load_funcs(cx, global, TestSuiteFunctions) != true)
- return 1;
- }
-
for(i = 0 ; args->scripts[i] ; i++) {
const char* filename = args->scripts[i];
diff --git a/src/couch/priv/couch_js/68/util.cpp b/src/couch/priv/couch_js/68/util.cpp
index 7717f1185..6e6105df5 100644
--- a/src/couch/priv/couch_js/68/util.cpp
+++ b/src/couch/priv/couch_js/68/util.cpp
@@ -135,12 +135,8 @@ couch_parse_args(int argc, const char* argv[])
return NULL;
args->eval = 0;
- args->use_http = 0;
- args->use_test_funs = 0;
args->stack_size = 64L * 1024L * 1024L;
args->scripts = nullptr;
- args->uri_file = nullptr;
- args->uri = nullptr;
while(i < argc) {
if(strcmp("-h", argv[i]) == 0) {
@@ -149,18 +145,12 @@ couch_parse_args(int argc, const char* argv[])
} else if(strcmp("-V", argv[i]) == 0) {
DISPLAY_VERSION;
exit(0);
- } else if(strcmp("-H", argv[i]) == 0) {
- args->use_http = 1;
- } else if(strcmp("-T", argv[i]) == 0) {
- args->use_test_funs = 1;
} else if(strcmp("-S", argv[i]) == 0) {
args->stack_size = atoi(argv[++i]);
if(args->stack_size <= 0) {
fprintf(stderr, "Invalid stack size.\n");
exit(2);
}
- } else if(strcmp("-u", argv[i]) == 0) {
- args->uri_file = argv[++i];
} else if(strcmp("--eval", argv[i]) == 0) {
args->eval = 1;
} else if(strcmp("--", argv[i]) == 0) {
diff --git a/src/couch/rebar.config.script b/src/couch/rebar.config.script
index ed5420f0a..59bd40fbb 100644
--- a/src/couch/rebar.config.script
+++ b/src/couch/rebar.config.script
@@ -132,29 +132,6 @@ end.
}
end.
-{CURL_CFLAGS, CURL_LDFLAGS} = case lists:keyfind(with_curl, 1, CouchConfig) of
- {with_curl, true} ->
- case os:type() of
- {win32, _} ->
- {
- "/DHAVE_CURL",
- "/DHAVE_CURL libcurl.lib"
- };
- {unix, freebsd} ->
- {
- "-DHAVE_CURL -I/usr/local/include",
- "-DHAVE_CURL -lcurl"
- };
- _ ->
- {
- "-DHAVE_CURL",
- "-DHAVE_CURL -lcurl"
- }
- end;
- _ ->
- {"", ""}
-end.
-
CouchJSSrc = case SMVsn of
"1.8.5" -> ["priv/couch_js/1.8.5/*.c"];
"60" -> ["priv/couch_js/60/*.cpp"];
@@ -164,13 +141,13 @@ end.
CouchJSEnv = case SMVsn of
"1.8.5" ->
[
- {"CFLAGS", JS_CFLAGS ++ " " ++ CURL_CFLAGS},
- {"LDFLAGS", JS_LDFLAGS ++ " " ++ CURL_LDFLAGS}
+ {"CFLAGS", JS_CFLAGS},
+ {"LDFLAGS", JS_LDFLAGS}
];
_ ->
[
- {"CXXFLAGS", JS_CFLAGS ++ " " ++ CURL_CFLAGS},
- {"LDFLAGS", JS_LDFLAGS ++ " " ++ CURL_LDFLAGS}
+ {"CXXFLAGS", JS_CFLAGS},
+ {"LDFLAGS", JS_LDFLAGS}
]
end.