summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2012-02-18 09:46:58 -0800
committerisaacs <i@izs.me>2012-02-18 09:46:58 -0800
commit31721da4b120ca2b1c0b6b9e93ce8beb5e810da3 (patch)
tree9a4da945ae4868c6dbd0c509f8f08c87b8776a92 /src
parent07872870213ed38c1978b37e9e2e22db733b40f3 (diff)
parentc1f474010e8e58793408fc1d8303aeb1a01ba735 (diff)
downloadnode-new-31721da4b120ca2b1c0b6b9e93ce8beb5e810da3.tar.gz
Merge remote-tracking branch 'ry/v0.6' into v0.6-merge
Conflicts: AUTHORS ChangeLog Makefile doc/about/index.html doc/api/tls.markdown doc/community/index.html doc/index.html doc/logos/index.html doc/template.html lib/http.js lib/tls.js src/node_version.h src/platform_win32.cc test/simple/test-tls-connect-given-socket.js
Diffstat (limited to 'src')
-rw-r--r--src/node.cc241
-rw-r--r--src/node_crypto.cc16
-rw-r--r--src/node_crypto.h2
-rw-r--r--src/node_main.cc41
-rw-r--r--src/pipe_wrap.cc5
-rw-r--r--src/tcp_wrap.cc5
6 files changed, 175 insertions, 135 deletions
diff --git a/src/node.cc b/src/node.cc
index 9a2d8faeb1..42a2f8c0d7 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -1290,76 +1290,6 @@ static Handle<Value> Cwd(const Arguments& args) {
}
-#ifdef _WIN32
-static Handle<Value> CwdForDrive(const Arguments& args) {
- HandleScope scope;
-
- if (args.Length() < 1) {
- Local<Value> exception = Exception::Error(
- String::New("process._cwdForDrive takes exactly 1 argument."));
- return ThrowException(exception);
- }
-
- Local<String> driveLetter = args[0]->ToString();
- if (driveLetter->Length() != 1) {
- Local<Value> exception = Exception::Error(
- String::New("Drive name should be 1 character."));
- return ThrowException(exception);
- }
-
- char drive;
-
- driveLetter->WriteAscii(&drive, 0, 1, 0);
- if (drive >= 'a' && drive <= 'z') {
- // Convert to uppercase
- drive += 'A' - 'a';
- } else if (drive < 'A' || drive > 'Z') {
- // Not a letter
- Local<Value> exception = Exception::Error(
- String::New("Drive name should be a letter."));
- return ThrowException(exception);
- }
-
- WCHAR env_key[] = L"=X:";
- env_key[1] = (WCHAR) drive;
-
- DWORD len = GetEnvironmentVariableW(env_key, NULL, 0);
- if (len == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
- // There is no current directory for that drive. Default to drive + ":\".
- Local<String> cwd = String::Concat(String::New(&drive, 1),
- String::New(":\\"));
- return scope.Close(cwd);
-
- } else if (len == 0) {
- // Error
- Local<Value> exception = Exception::Error(
- String::New(winapi_strerror(GetLastError())));
- return ThrowException(exception);
- }
-
- WCHAR* buffer = new WCHAR[len];
- if (buffer == NULL) {
- Local<Value> exception = Exception::Error(
- String::New("Out of memory."));
- return ThrowException(exception);
- }
-
- DWORD len2 = GetEnvironmentVariableW(env_key, buffer, len);
- if (len2 == 0 || len2 >= len) {
- // Error
- delete[] buffer;
- Local<Value> exception = Exception::Error(
- String::New(winapi_strerror(GetLastError())));
- return ThrowException(exception);
- }
-
- Local<String> cwd = String::New(reinterpret_cast<uint16_t*>(buffer), len2);
- delete[] buffer;
- return scope.Close(cwd);
-}
-#endif
-
-
static Handle<Value> Umask(const Arguments& args) {
HandleScope scope;
unsigned int old;
@@ -1883,12 +1813,28 @@ static void ProcessTitleSetter(Local<String> property,
static Handle<Value> EnvGetter(Local<String> property,
const AccessorInfo& info) {
+ HandleScope scope;
+#ifdef __POSIX__
String::Utf8Value key(property);
const char* val = getenv(*key);
if (val) {
- HandleScope scope;
return scope.Close(String::New(val));
}
+#else // _WIN32
+ String::Value key(property);
+ WCHAR buffer[32767]; // The maximum size allowed for environment variables.
+ DWORD result = GetEnvironmentVariableW(reinterpret_cast<WCHAR*>(*key),
+ buffer,
+ ARRAY_SIZE(buffer));
+ // If result >= sizeof buffer the buffer was too small. That should never
+ // happen. If result == 0 and result != ERROR_SUCCESS the variable was not
+ // not found.
+ if ((result > 0 || GetLastError() == ERROR_SUCCESS) &&
+ result < ARRAY_SIZE(buffer)) {
+ return scope.Close(String::New(reinterpret_cast<uint16_t*>(buffer), result));
+ }
+#endif
+ // Not found
return Undefined();
}
@@ -1897,66 +1843,82 @@ static Handle<Value> EnvSetter(Local<String> property,
Local<Value> value,
const AccessorInfo& info) {
HandleScope scope;
+#ifdef __POSIX__
String::Utf8Value key(property);
String::Utf8Value val(value);
-
-#ifdef __POSIX__
setenv(*key, *val, 1);
-#else // __WIN32__
- int n = key.length() + val.length() + 2;
- char* pair = new char[n];
- snprintf(pair, n, "%s=%s", *key, *val);
- int r = _putenv(pair);
- if (r) {
- fprintf(stderr, "error putenv: '%s'\n", pair);
+#else // _WIN32
+ String::Value key(property);
+ String::Value val(value);
+ WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
+ // Environment variables that start with '=' are read-only.
+ if (key_ptr[0] != L'=') {
+ SetEnvironmentVariableW(key_ptr, reinterpret_cast<WCHAR*>(*val));
}
- delete [] pair;
#endif
-
- return value;
+ // Whether it worked or not, always return rval.
+ return scope.Close(value);
}
static Handle<Integer> EnvQuery(Local<String> property,
const AccessorInfo& info) {
+ HandleScope scope;
+#ifdef __POSIX__
String::Utf8Value key(property);
if (getenv(*key)) {
- HandleScope scope;
return scope.Close(Integer::New(None));
}
- return Handle<Integer>();
+#else // _WIN32
+ String::Value key(property);
+ WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
+ if (GetEnvironmentVariableW(key_ptr, NULL, 0) > 0 ||
+ GetLastError() == ERROR_SUCCESS) {
+ if (key_ptr[0] == L'=') {
+ // Environment variables that start with '=' are hidden and read-only.
+ return scope.Close(Integer::New(v8::ReadOnly ||
+ v8::DontDelete ||
+ v8::DontEnum));
+ } else {
+ return scope.Close(Integer::New(None));
+ }
+ }
+#endif
+ // Not found
+ return scope.Close(Handle<Integer>());
}
static Handle<Boolean> EnvDeleter(Local<String> property,
const AccessorInfo& info) {
HandleScope scope;
-
- String::Utf8Value key(property);
-
- if (getenv(*key)) {
#ifdef __POSIX__
- unsetenv(*key); // prototyped as `void unsetenv(const char*)` on some platforms
+ String::Utf8Value key(property);
+ // prototyped as `void unsetenv(const char*)` on some platforms
+ if (unsetenv(*key) < 0) {
+ // Deletion failed. Return true if the key wasn't there in the first place,
+ // false if it is still there.
+ return scope.Close(Boolean::New(getenv(*key) == NULL));
+ };
#else
- int n = key.length() + 2;
- char* pair = new char[n];
- snprintf(pair, n, "%s=", *key);
- int r = _putenv(pair);
- if (r) {
- fprintf(stderr, "error unsetenv: '%s'\n", pair);
- }
- delete [] pair;
-#endif
- return True();
+ String::Value key(property);
+ WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
+ if (key_ptr[0] == L'=' || !SetEnvironmentVariableW(key_ptr, NULL)) {
+ // Deletion failed. Return true if the key wasn't there in the first place,
+ // false if it is still there.
+ bool rv = GetEnvironmentVariableW(key_ptr, NULL, NULL) == 0 &&
+ GetLastError() != ERROR_SUCCESS;
+ return scope.Close(Boolean::New(rv));
}
-
- return False();
+#endif
+ // It worked
+ return v8::True();
}
static Handle<Array> EnvEnumerator(const AccessorInfo& info) {
HandleScope scope;
-
+#ifdef __POSIX__
int size = 0;
while (environ[size]) size++;
@@ -1968,7 +1930,32 @@ static Handle<Array> EnvEnumerator(const AccessorInfo& info) {
const int length = s ? s - var : strlen(var);
env->Set(i, String::New(var, length));
}
-
+#else // _WIN32
+ WCHAR* environment = GetEnvironmentStringsW();
+ if (environment == NULL) {
+ // This should not happen.
+ return scope.Close(Handle<Array>());
+ }
+ Local<Array> env = Array::New();
+ WCHAR* p = environment;
+ int i = 0;
+ while (*p != NULL) {
+ WCHAR *s;
+ if (*p == L'=') {
+ // If the key starts with '=' it is a hidden environment variable.
+ p += wcslen(p) + 1;
+ continue;
+ } else {
+ s = wcschr(p, L'=');
+ }
+ if (!s) {
+ s = p + wcslen(p);
+ }
+ env->Set(i++, String::New(reinterpret_cast<uint16_t*>(p), s - p));
+ p = s + wcslen(s) + 1;
+ }
+ FreeEnvironmentStringsW(environment);
+#endif
return scope.Close(env);
}
@@ -2127,10 +2114,6 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) {
NODE_SET_METHOD(process, "chdir", Chdir);
NODE_SET_METHOD(process, "cwd", Cwd);
-#ifdef _WIN32
- NODE_SET_METHOD(process, "_cwdForDrive", CwdForDrive);
-#endif
-
NODE_SET_METHOD(process, "umask", Umask);
#ifdef __POSIX__
@@ -2416,13 +2399,14 @@ DWORD WINAPI EnableDebugThreadProc(void* arg) {
}
-static int GetDebugSignalHandlerMappingName(DWORD pid, char* buf, size_t buf_len) {
- return snprintf(buf, buf_len, "node-debug-handler-%u", pid);
+static int GetDebugSignalHandlerMappingName(DWORD pid, wchar_t* buf,
+ size_t buf_len) {
+ return _snwprintf(buf, buf_len, L"node-debug-handler-%u", pid);
}
static int RegisterDebugSignalHandler() {
- char mapping_name[32];
+ wchar_t mapping_name[32];
HANDLE mapping_handle;
DWORD pid;
LPTHREAD_START_ROUTINE* handler;
@@ -2431,11 +2415,11 @@ static int RegisterDebugSignalHandler() {
if (GetDebugSignalHandlerMappingName(pid,
mapping_name,
- sizeof mapping_name) < 0) {
+ ARRAY_SIZE(mapping_name)) < 0) {
return -1;
}
- mapping_handle = CreateFileMappingA(INVALID_HANDLE_VALUE,
+ mapping_handle = CreateFileMappingW(INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
@@ -2445,11 +2429,12 @@ static int RegisterDebugSignalHandler() {
return -1;
}
- handler = (LPTHREAD_START_ROUTINE*) MapViewOfFile(mapping_handle,
- FILE_MAP_ALL_ACCESS,
- 0,
- 0,
- sizeof *handler);
+ handler = reinterpret_cast<LPTHREAD_START_ROUTINE*>(
+ MapViewOfFile(mapping_handle,
+ FILE_MAP_ALL_ACCESS,
+ 0,
+ 0,
+ sizeof *handler));
if (handler == NULL) {
CloseHandle(mapping_handle);
return -1;
@@ -2470,7 +2455,7 @@ static Handle<Value> DebugProcess(const Arguments& args) {
HANDLE process = NULL;
HANDLE thread = NULL;
HANDLE mapping = NULL;
- char mapping_name[32];
+ wchar_t mapping_name[32];
LPTHREAD_START_ROUTINE* handler = NULL;
if (args.Length() != 1) {
@@ -2492,22 +2477,24 @@ static Handle<Value> DebugProcess(const Arguments& args) {
if (GetDebugSignalHandlerMappingName(pid,
mapping_name,
- sizeof mapping_name) < 0) {
+ ARRAY_SIZE(mapping_name)) < 0) {
rv = ThrowException(ErrnoException(errno, "sprintf"));
goto out;
}
- mapping = OpenFileMapping(FILE_MAP_READ, FALSE, mapping_name);
+ mapping = OpenFileMappingW(FILE_MAP_READ, FALSE, mapping_name);
if (mapping == NULL) {
- rv = ThrowException(WinapiErrnoException(GetLastError(), "sprintf"));
+ rv = ThrowException(WinapiErrnoException(GetLastError(),
+ "OpenFileMappingW"));
goto out;
}
- handler = (LPTHREAD_START_ROUTINE*) MapViewOfFile(mapping,
- FILE_MAP_READ,
- 0,
- 0,
- sizeof *handler);
+ handler = reinterpret_cast<LPTHREAD_START_ROUTINE*>(
+ MapViewOfFile(mapping,
+ FILE_MAP_READ,
+ 0,
+ 0,
+ sizeof *handler));
if (handler == NULL || *handler == NULL) {
rv = ThrowException(WinapiErrnoException(GetLastError(), "MapViewOfFile"));
goto out;
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index 41bb2bd40e..b011d52061 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -908,6 +908,8 @@ Handle<Value> Connection::New(const Arguments& args) {
SSL_set_app_data(p->ssl_, p);
+ if (is_server) SSL_set_info_callback(p->ssl_, SSLInfoCallback);
+
#ifdef OPENSSL_NPN_NEGOTIATED
if (is_server) {
// Server should advertise NPN protocols
@@ -970,6 +972,20 @@ Handle<Value> Connection::New(const Arguments& args) {
}
+void Connection::SSLInfoCallback(const SSL *ssl, int where, int ret) {
+ if (where & SSL_CB_HANDSHAKE_START) {
+ HandleScope scope;
+ Connection* c = static_cast<Connection*>(SSL_get_app_data(ssl));
+ MakeCallback(c->handle_, "onhandshakestart", 0, NULL);
+ }
+ if (where & SSL_CB_HANDSHAKE_DONE) {
+ HandleScope scope;
+ Connection* c = static_cast<Connection*>(SSL_get_app_data(ssl));
+ MakeCallback(c->handle_, "onhandshakedone", 0, NULL);
+ }
+}
+
+
Handle<Value> Connection::EncIn(const Arguments& args) {
HandleScope scope;
diff --git a/src/node_crypto.h b/src/node_crypto.h
index 4cde964da4..87a5340147 100644
--- a/src/node_crypto.h
+++ b/src/node_crypto.h
@@ -190,6 +190,8 @@ class Connection : ObjectWrap {
}
private:
+ static void SSLInfoCallback(const SSL *ssl, int where, int ret);
+
BIO *bio_read_;
BIO *bio_write_;
SSL *ssl_;
diff --git a/src/node_main.cc b/src/node_main.cc
index 3100149868..dba8b69203 100644
--- a/src/node_main.cc
+++ b/src/node_main.cc
@@ -21,6 +21,47 @@
#include <node.h>
+#ifdef _WIN32
+int wmain(int argc, wchar_t *wargv[]) {
+ // Convert argv to to UTF8
+ char** argv = new char*[argc];
+ for (int i = 0; i < argc; i++) {
+ // Compute the size of the required buffer
+ DWORD size = WideCharToMultiByte(CP_UTF8,
+ 0,
+ wargv[i],
+ -1,
+ NULL,
+ 0,
+ NULL,
+ NULL);
+ if (size == 0) {
+ // This should never happen.
+ fprintf(stderr, "Could not convert arguments to utf8.");
+ exit(1);
+ }
+ // Do the actual conversion
+ argv[i] = new char[size];
+ DWORD result = WideCharToMultiByte(CP_UTF8,
+ 0,
+ wargv[i],
+ -1,
+ argv[i],
+ size,
+ NULL,
+ NULL);
+ if (result == 0) {
+ // This should never happen.
+ fprintf(stderr, "Could not convert arguments to utf8.");
+ exit(1);
+ }
+ }
+ // Now that conversion is done, we can finally start.
+ return node::Start(argc, argv);
+}
+#else
+// UNIX
int main(int argc, char *argv[]) {
return node::Start(argc, argv);
}
+#endif
diff --git a/src/pipe_wrap.cc b/src/pipe_wrap.cc
index 6c3887d84f..c99fe47397 100644
--- a/src/pipe_wrap.cc
+++ b/src/pipe_wrap.cc
@@ -204,10 +204,7 @@ void PipeWrap::OnConnection(uv_stream_t* handle, int status) {
PipeWrap* client_wrap =
static_cast<PipeWrap*>(client_obj->GetPointerFromInternalField(0));
- int r = uv_accept(handle, (uv_stream_t*)&client_wrap->handle_);
-
- // uv_accept should always work.
- assert(r == 0);
+ if (uv_accept(handle, (uv_stream_t*)&client_wrap->handle_)) return;
// Successful accept. Call the onconnection callback in JavaScript land.
Local<Value> argv[1] = { client_obj };
diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc
index 688d7d7190..14e6d3ed66 100644
--- a/src/tcp_wrap.cc
+++ b/src/tcp_wrap.cc
@@ -366,10 +366,7 @@ void TCPWrap::OnConnection(uv_stream_t* handle, int status) {
TCPWrap* client_wrap =
static_cast<TCPWrap*>(client_obj->GetPointerFromInternalField(0));
- int r = uv_accept(handle, (uv_stream_t*)&client_wrap->handle_);
-
- // uv_accept should always work.
- assert(r == 0);
+ if (uv_accept(handle, (uv_stream_t*)&client_wrap->handle_)) return;
// Successful accept. Call the onconnection callback in JavaScript land.
argv[0] = client_obj;