diff options
author | isaacs <i@izs.me> | 2012-02-18 09:46:58 -0800 |
---|---|---|
committer | isaacs <i@izs.me> | 2012-02-18 09:46:58 -0800 |
commit | 31721da4b120ca2b1c0b6b9e93ce8beb5e810da3 (patch) | |
tree | 9a4da945ae4868c6dbd0c509f8f08c87b8776a92 /src | |
parent | 07872870213ed38c1978b37e9e2e22db733b40f3 (diff) | |
parent | c1f474010e8e58793408fc1d8303aeb1a01ba735 (diff) | |
download | node-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.cc | 241 | ||||
-rw-r--r-- | src/node_crypto.cc | 16 | ||||
-rw-r--r-- | src/node_crypto.h | 2 | ||||
-rw-r--r-- | src/node_main.cc | 41 | ||||
-rw-r--r-- | src/pipe_wrap.cc | 5 | ||||
-rw-r--r-- | src/tcp_wrap.cc | 5 |
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; |