mirror of https://gitee.com/bigwinds/arangodb
sendFile
This commit is contained in:
parent
6df7dfce5e
commit
f58e1a4b9a
|
@ -1,6 +1,6 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true, nonpropdel: true, proto: true */
|
||||
/*jslint indent: 2, nomen: true, maxlen: 120, sloppy: true, vars: true, white: true, plusplus: true, nonpropdel: true, proto: true */
|
||||
/*global require, module, Module, FS_MOVE, FS_REMOVE, FS_EXISTS, FS_IS_DIRECTORY, FS_IS_FILE,
|
||||
FS_LIST_TREE, FS_UNZIP_FILE, FS_ZIP_FILE, SYS_DOWNLOAD,
|
||||
FS_LIST_TREE, FS_UNZIP_FILE, FS_ZIP_FILE, SYS_DOWNLOAD, SYS_SEND_FILE,
|
||||
SYS_EXECUTE, SYS_LOAD, SYS_LOG, SYS_LOG_LEVEL, SYS_MD5, SYS_OUTPUT, SYS_PROCESS_STAT, SYS_RAND,
|
||||
SYS_READ, SYS_SPRINTF, SYS_TIME, SYS_START_PAGER, SYS_STOP_PAGER, SYS_SHA256, SYS_WAIT,
|
||||
SYS_GETLINE, SYS_PARSE, SYS_SAVE, SYS_IMPORT_CSV_FILE, SYS_IMPORT_JSON_FILE, PACKAGE_PATH,
|
||||
|
@ -12,7 +12,7 @@
|
|||
COLOR_BOLD_WHITE, COLOR_YELLOW, COLOR_BOLD_YELLOW, COLOR_CYAN, COLOR_BOLD_CYAN, COLOR_MAGENTA,
|
||||
COLOR_BOLD_MAGENTA, PRETTY_PRINT, VALGRIND, VERSION, UPGRADE,
|
||||
BYTES_SENT_DISTRIBUTION, BYTES_RECEIVED_DISTRIBUTION, CONNECTION_TIME_DISTRIBUTION,
|
||||
REQUEST_TIME_DISTRIBUTION, THREAD_NUMBER, HOME, PATH_SEPARATOR, DEVELOPMENT_MODE */
|
||||
REQUEST_TIME_DISTRIBUTION, HOME, DEVELOPMENT_MODE, THREAD_NUMBER, PATH_SEPARATOR */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief module "internal"
|
||||
|
@ -62,6 +62,11 @@
|
|||
internal.download = SYS_DOWNLOAD;
|
||||
delete SYS_DOWNLOAD;
|
||||
}
|
||||
|
||||
if (typeof SYS_SEND_FILE !== "undefined") {
|
||||
internal.sendFile = SYS_SEND_FILE;
|
||||
delete SYS_SEND_FILE;
|
||||
}
|
||||
|
||||
if (typeof SYS_EXECUTE !== "undefined") {
|
||||
internal.execute = SYS_EXECUTE;
|
||||
|
@ -301,7 +306,7 @@
|
|||
/// @brief modules path
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.MODULES_PATH = "";
|
||||
internal.MODULES_PATH = [];
|
||||
|
||||
if (typeof MODULES_PATH !== "undefined") {
|
||||
internal.MODULES_PATH = MODULES_PATH;
|
||||
|
@ -309,16 +314,27 @@
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief node modules path
|
||||
/// @brief package path
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.PACKAGE_PATH = "";
|
||||
internal.PACKAGE_PATH = [];
|
||||
|
||||
if (typeof PACKAGE_PATH !== "undefined") {
|
||||
internal.PACKAGE_PATH = PACKAGE_PATH;
|
||||
delete PACKAGE_PATH;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief app path
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.APP_PATH = [];
|
||||
|
||||
if (typeof APP_PATH !== "undefined") {
|
||||
internal.APP_PATH = APP_PATH;
|
||||
delete APP_PATH;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief quiet flag
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, plusplus: true */
|
||||
/*jslint indent: 2, nomen: true, maxlen: 120, sloppy: true, plusplus: true */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief monkey-patches to built-in prototypes
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true, nonpropdel: true */
|
||||
/*jslint indent: 2, nomen: true, maxlen: 120, sloppy: true, vars: true, white: true, plusplus: true, nonpropdel: true */
|
||||
/*global require, ArangoConnection, print, SYS_ARANGO */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
|
||||
/*global require, SYS_UNIT_TESTS */
|
||||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, nonpropdel: true, white: true, plusplus: true, evil: true */
|
||||
/*global require, IS_EXECUTE_SCRIPT, IS_CHECK_SCRIPT, IS_UNIT_TESTS, IS_JS_LINT */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief ArangoShell client API
|
||||
|
@ -108,10 +108,8 @@ function clear () {
|
|||
|
||||
if (internal.ARANGO_QUIET !== true && ! special) {
|
||||
if (typeof internal.arango !== "undefined") {
|
||||
if (typeof internal.arango.isConnected !== "undefined") {
|
||||
if (internal.arango.isConnected() && typeof SYS_UNIT_TESTS === "undefined") {
|
||||
internal.print(arangosh.HELP);
|
||||
}
|
||||
if (typeof internal.arango.isConnected !== "undefined" && internal.arango.isConnected()) {
|
||||
internal.print(arangosh.HELP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -133,8 +131,6 @@ var arango = require("org/arangodb").arango;
|
|||
/// @brief read rc file
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
require("console").log("############## %s", typeof SYS_UNIT_TESTS);
|
||||
|
||||
if (! (IS_EXECUTE_SCRIPT || IS_CHECK_SCRIPT || IS_UNIT_TESTS || IS_JS_LINT)) {
|
||||
(function () {
|
||||
var fs = require("fs");
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 120, sloppy: true, vars: true, white: true, plusplus: true, nonpropdel: true, proto: true */
|
||||
/*global require, module, Module, FS_MOVE, FS_REMOVE, FS_EXISTS, FS_IS_DIRECTORY, FS_IS_FILE,
|
||||
FS_LIST_TREE, FS_UNZIP_FILE, FS_ZIP_FILE, SYS_DOWNLOAD,
|
||||
FS_LIST_TREE, FS_UNZIP_FILE, FS_ZIP_FILE, SYS_DOWNLOAD, SYS_SEND_FILE,
|
||||
SYS_EXECUTE, SYS_LOAD, SYS_LOG, SYS_LOG_LEVEL, SYS_MD5, SYS_OUTPUT, SYS_PROCESS_STAT, SYS_RAND,
|
||||
SYS_READ, SYS_SPRINTF, SYS_TIME, SYS_START_PAGER, SYS_STOP_PAGER, SYS_SHA256, SYS_WAIT,
|
||||
SYS_GETLINE, SYS_PARSE, SYS_SAVE, SYS_IMPORT_CSV_FILE, SYS_IMPORT_JSON_FILE, PACKAGE_PATH,
|
||||
|
@ -62,6 +62,11 @@
|
|||
internal.download = SYS_DOWNLOAD;
|
||||
delete SYS_DOWNLOAD;
|
||||
}
|
||||
|
||||
if (typeof SYS_SEND_FILE !== "undefined") {
|
||||
internal.sendFile = SYS_SEND_FILE;
|
||||
delete SYS_SEND_FILE;
|
||||
}
|
||||
|
||||
if (typeof SYS_EXECUTE !== "undefined") {
|
||||
internal.execute = SYS_EXECUTE;
|
||||
|
|
|
@ -812,7 +812,7 @@ bool TRI_fsync (int fd) {
|
|||
/// @brief slurps in a file
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
char* TRI_SlurpFile (TRI_memory_zone_t* zone, char const* filename) {
|
||||
char* TRI_SlurpFile (TRI_memory_zone_t* zone, char const* filename, size_t* length) {
|
||||
TRI_string_buffer_t result;
|
||||
char buffer[10240];
|
||||
int fd;
|
||||
|
@ -856,6 +856,10 @@ char* TRI_SlurpFile (TRI_memory_zone_t* zone, char const* filename) {
|
|||
}
|
||||
}
|
||||
|
||||
if (length != NULL) {
|
||||
*length = TRI_LengthStringBuffer(&result);
|
||||
}
|
||||
|
||||
TRI_CLOSE(fd);
|
||||
return result._buffer;
|
||||
}
|
||||
|
|
|
@ -181,7 +181,7 @@ bool TRI_fsync (int fd);
|
|||
/// @brief slurps in a file
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
char* TRI_SlurpFile (TRI_memory_zone_t*, char const* filename);
|
||||
char* TRI_SlurpFile (TRI_memory_zone_t*, char const* filename, size_t* length);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief creates a lock file based on the PID
|
||||
|
|
|
@ -151,7 +151,7 @@ string const& ScriptLoader::findScript (string const& name) {
|
|||
|
||||
for (size_t i = 0; i < parts.size(); i++) {
|
||||
char* filename = TRI_Concatenate2File(parts.at(i).c_str(), name.c_str());
|
||||
char* result = TRI_SlurpFile(TRI_CORE_MEM_ZONE, filename);
|
||||
char* result = TRI_SlurpFile(TRI_CORE_MEM_ZONE, filename, NULL);
|
||||
|
||||
if (result == 0 && (i == parts.size() - 1)) {
|
||||
LOGGER_ERROR("cannot locate file '" << StringUtils::correctPath(name) << "': " << TRI_last_error());
|
||||
|
|
|
@ -159,7 +159,7 @@ static bool LoadJavaScriptFile (char const* filename,
|
|||
bool useGlobalContext) {
|
||||
v8::HandleScope handleScope;
|
||||
|
||||
char* content = TRI_SlurpFile(TRI_UNKNOWN_MEM_ZONE, filename);
|
||||
char* content = TRI_SlurpFile(TRI_UNKNOWN_MEM_ZONE, filename, NULL);
|
||||
|
||||
if (content == 0) {
|
||||
LOG_TRACE("cannot load java script file '%s': %s", filename, TRI_last_error());
|
||||
|
@ -356,9 +356,10 @@ static v8::Handle<v8::Value> JS_Parse (v8::Arguments const& argv) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief downloads data from a URL
|
||||
///
|
||||
/// @FUN{internal.download(@FA{url})}
|
||||
/// @FUN{internal.download(@FA{url}, @FA{method}, @FA{outfile}, @FA{timeout})}
|
||||
///
|
||||
/// Downloads the data from the URL specified by @FA{url}.
|
||||
/// Downloads the data from the URL specified by @FA{url} and saves the
|
||||
/// response body to @FA{outfile}.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> JS_Download (v8::Arguments const& argv) {
|
||||
|
@ -481,7 +482,7 @@ static v8::Handle<v8::Value> JS_Download (v8::Arguments const& argv) {
|
|||
}
|
||||
result->Set(v8::String::New("headers"), headers);
|
||||
|
||||
if (returnCode == SimpleHttpResult::HTTP_STATUS_OK) {
|
||||
if (returnCode >= 200 && returnCode <= 299) {
|
||||
try {
|
||||
FileUtils::spit(outfile, response->getBody().str());
|
||||
}
|
||||
|
@ -505,6 +506,153 @@ static v8::Handle<v8::Value> JS_Download (v8::Arguments const& argv) {
|
|||
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(TRI_ERROR_INTERNAL, "too many redirects")));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief send data from a file to a URL
|
||||
///
|
||||
/// @FUN{internal.sendFile(@FA{url}, @FA{method}, @FA{file})}
|
||||
///
|
||||
/// Sends the data from the file @FA{file} to the URL specified by @FA{url}.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> JS_SendFile (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (argv.Length() < 3) {
|
||||
return scope.Close(v8::ThrowException(v8::String::New("usage: sendFile(<url>, <method>, <infile>, <outfile>, <timeout>)")));
|
||||
}
|
||||
|
||||
string url = TRI_ObjectToString(argv[0]);
|
||||
|
||||
HttpRequest::HttpRequestType method = HttpRequest::HTTP_REQUEST_POST;
|
||||
const string methodString = TRI_ObjectToString(argv[1]);
|
||||
if (methodString == "put") {
|
||||
method = HttpRequest::HTTP_REQUEST_PUT;
|
||||
}
|
||||
else if (methodString == "patch") {
|
||||
method = HttpRequest::HTTP_REQUEST_PATCH;
|
||||
}
|
||||
|
||||
const string infile = TRI_ObjectToString(argv[2]);
|
||||
const string outfile = TRI_ObjectToString(argv[3]);
|
||||
|
||||
double timeout = 10.0;
|
||||
if (argv.Length() > 4) {
|
||||
timeout = TRI_ObjectToDouble(argv[4]);
|
||||
}
|
||||
|
||||
if (! TRI_ExistsFile(infile.c_str())) {
|
||||
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(TRI_ERROR_FILE_NOT_FOUND)));
|
||||
}
|
||||
|
||||
if (TRI_ExistsFile(outfile.c_str())) {
|
||||
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(TRI_ERROR_CANNOT_OVERWRITE_FILE)));
|
||||
}
|
||||
|
||||
string endpoint;
|
||||
string relative;
|
||||
|
||||
if (url.substr(0, 7) == "http://") {
|
||||
size_t found = url.find('/', 7);
|
||||
|
||||
relative = "/";
|
||||
if (found != string::npos) {
|
||||
relative.append(url.substr(found + 1));
|
||||
endpoint = "tcp://" + url.substr(7, found - 7) + ":80";
|
||||
}
|
||||
else {
|
||||
endpoint = "tcp://" + url.substr(7) + ":80";
|
||||
}
|
||||
}
|
||||
else if (url.substr(0, 8) == "https://") {
|
||||
size_t found = url.find('/', 8);
|
||||
|
||||
relative = "/";
|
||||
if (found != string::npos) {
|
||||
relative.append(url.substr(found + 1));
|
||||
endpoint = "ssl://" + url.substr(8, found - 8) + ":443";
|
||||
}
|
||||
else {
|
||||
endpoint = "ssl://" + url.substr(8) + ":443";
|
||||
}
|
||||
}
|
||||
else {
|
||||
return scope.Close(v8::ThrowException(v8::String::New("unsupported URL specified")));
|
||||
}
|
||||
|
||||
size_t bodySize;
|
||||
char* body = TRI_SlurpFile(TRI_UNKNOWN_MEM_ZONE, infile.c_str(), &bodySize);
|
||||
|
||||
if (body == 0) {
|
||||
return scope.Close(v8::ThrowException(v8::String::New("could not read file")));
|
||||
}
|
||||
|
||||
LOGGER_TRACE("sending file '" << infile << "'. endpoint: " << endpoint << ", relative URL: " << url);
|
||||
|
||||
GeneralClientConnection* connection = GeneralClientConnection::factory(Endpoint::clientFactory(endpoint), timeout, timeout, 3);
|
||||
|
||||
if (connection == 0) {
|
||||
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(TRI_ERROR_OUT_OF_MEMORY)));
|
||||
}
|
||||
|
||||
SimpleHttpClient client(connection, timeout, false);
|
||||
|
||||
v8::Handle<v8::Object> result = v8::Object::New();
|
||||
|
||||
// connect to server and get version number
|
||||
map<string, string> headerFields;
|
||||
SimpleHttpResult* response = client.request(method, relative, body, bodySize, headerFields);
|
||||
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, body);
|
||||
|
||||
int returnCode;
|
||||
string returnMessage;
|
||||
|
||||
if (! response || ! response->isComplete()) {
|
||||
// save error message
|
||||
returnMessage = client.getErrorMessage();
|
||||
returnCode = 500;
|
||||
|
||||
if (response && response->getHttpReturnCode() > 0) {
|
||||
returnCode = response->getHttpReturnCode();
|
||||
}
|
||||
}
|
||||
else {
|
||||
returnMessage = response->getHttpReturnMessage();
|
||||
returnCode = response->getHttpReturnCode();
|
||||
|
||||
result->Set(v8::String::New("code"), v8::Number::New(returnCode));
|
||||
result->Set(v8::String::New("message"), v8::String::New(returnMessage.c_str()));
|
||||
|
||||
const map<string, string> responseHeaders = response->getHeaderFields();
|
||||
map<string, string>::const_iterator it;
|
||||
|
||||
v8::Handle<v8::Object> headers = v8::Object::New();
|
||||
for (it = responseHeaders.begin(); it != responseHeaders.end(); ++it) {
|
||||
headers->Set(v8::String::New((*it).first.c_str()), v8::String::New((*it).second.c_str()));
|
||||
}
|
||||
result->Set(v8::String::New("headers"), headers);
|
||||
|
||||
if (returnCode >= 200 || returnCode <= 299) {
|
||||
try {
|
||||
FileUtils::spit(outfile, response->getBody().str());
|
||||
}
|
||||
catch (...) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result->Set(v8::String::New("code"), v8::Number::New(returnCode));
|
||||
result->Set(v8::String::New("message"), v8::String::New(returnMessage.c_str()));
|
||||
|
||||
if (response) {
|
||||
delete response;
|
||||
}
|
||||
|
||||
delete connection;
|
||||
return scope.Close(result);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief executes a script
|
||||
///
|
||||
|
@ -903,7 +1051,7 @@ static v8::Handle<v8::Value> JS_Load (v8::Arguments const& argv) {
|
|||
return scope.Close(v8::ThrowException(v8::String::New("<filename> must be a string")));
|
||||
}
|
||||
|
||||
char* content = TRI_SlurpFile(TRI_UNKNOWN_MEM_ZONE, *name);
|
||||
char* content = TRI_SlurpFile(TRI_UNKNOWN_MEM_ZONE, *name, NULL);
|
||||
|
||||
if (content == 0) {
|
||||
return scope.Close(v8::ThrowException(v8::String::New(TRI_last_error())));
|
||||
|
@ -1349,7 +1497,7 @@ static v8::Handle<v8::Value> JS_Read (v8::Arguments const& argv) {
|
|||
return scope.Close(v8::ThrowException(v8::String::New("<filename> must be a string")));
|
||||
}
|
||||
|
||||
char* content = TRI_SlurpFile(TRI_UNKNOWN_MEM_ZONE, *name);
|
||||
char* content = TRI_SlurpFile(TRI_UNKNOWN_MEM_ZONE, *name, NULL);
|
||||
|
||||
if (content == 0) {
|
||||
return scope.Close(v8::ThrowException(v8::String::New(TRI_last_error())));
|
||||
|
@ -2080,6 +2228,7 @@ void TRI_InitV8Utils (v8::Handle<v8::Context> context,
|
|||
TRI_AddGlobalFunctionVocbase(context, "FS_ZIP_FILE", JS_ZipFile);
|
||||
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_DOWNLOAD", JS_Download);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_SEND_FILE", JS_SendFile);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_EXECUTE", JS_Execute);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_GETLINE", JS_Getline);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_LOAD", JS_Load);
|
||||
|
|
Loading…
Reference in New Issue