Compare commits
132 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f4e0c02b5 | ||
|
|
7fd1c08b16 | ||
|
|
ff942c6b39 | ||
|
|
eb40dcb097 | ||
|
|
007ddcd2cd | ||
|
|
4cdf9d4158 | ||
|
|
49ac083dc1 | ||
|
|
3fc01d9770 | ||
|
|
dea49e3d19 | ||
|
|
942b92a06e | ||
|
|
aff91f79ae | ||
|
|
f9fec3a2d6 | ||
|
|
f6bce20e5e | ||
|
|
93aad55342 | ||
|
|
fdb0eb5825 | ||
|
|
3a9b08f156 | ||
|
|
9ef962f9ee | ||
|
|
97d355c273 | ||
|
|
b93a7cc99e | ||
|
|
ed44098cf6 | ||
|
|
b31d5ac639 | ||
|
|
cfe0f4226b | ||
|
|
771ba34ca7 | ||
|
|
6312e889b1 | ||
|
|
e06ce7562c | ||
|
|
b3af074a02 | ||
|
|
98990b9779 | ||
|
|
5724b54d2e | ||
|
|
8b2a3354f9 | ||
|
|
fdbfc9ceb7 | ||
|
|
3e853e627e | ||
|
|
96ede8cc9b | ||
|
|
ef27d56cc1 | ||
|
|
0c91a835ff | ||
|
|
827b9c5f1f | ||
|
|
509a676128 | ||
|
|
ce9caa237f | ||
|
|
e150bc4f2b | ||
|
|
b4712bf1ac | ||
|
|
dc578724b1 | ||
|
|
a745d19ce7 | ||
|
|
9cd510846e | ||
|
|
5e37e10e41 | ||
|
|
e8d268fd5f | ||
|
|
4d186f270f | ||
|
|
028b33b18a | ||
|
|
4e204f37fd | ||
|
|
e00c2ec5e3 | ||
|
|
7ba30a4c2e | ||
|
|
3210809d0a | ||
|
|
d1a2628499 | ||
|
|
0d8d04e585 | ||
|
|
421b6e89aa | ||
|
|
25118b0a26 | ||
|
|
fc57df283c | ||
|
|
b267dc458d | ||
|
|
3056c2ca76 | ||
|
|
c72223e2a9 | ||
|
|
8b3ba47f88 | ||
|
|
eab8bebced | ||
|
|
2d65f3c59a | ||
|
|
d32971a8cb | ||
|
|
deb100fb17 | ||
|
|
bf0802402d | ||
|
|
e357acc55b | ||
|
|
b8e9bf0993 | ||
|
|
78487b6256 | ||
|
|
691497babe | ||
|
|
bbf7e8ed5e | ||
|
|
effc4469d0 | ||
|
|
1b8dd65d6e | ||
|
|
ddfc6b78cc | ||
|
|
973153d1cc | ||
|
|
9f9a4cb928 | ||
|
|
e8bc80cf15 | ||
|
|
9a16f1c7d0 | ||
|
|
8caf7fdb05 | ||
|
|
5b02d564c3 | ||
|
|
901ebed8ff | ||
|
|
7097eca5a7 | ||
|
|
5208abe723 | ||
|
|
5f97c9a005 | ||
|
|
128d1bab2a | ||
|
|
701ae3c995 | ||
|
|
8cc9ac0df2 | ||
|
|
d05afa50e6 | ||
|
|
6bcd96c253 | ||
|
|
360f4b78dd | ||
|
|
b1c90a4e22 | ||
|
|
7e8735b3fe | ||
|
|
87b6dc21c8 | ||
|
|
fc80ee947a | ||
|
|
b62ecdc5bb | ||
|
|
073fbea0f5 | ||
|
|
82cfdb88fa | ||
|
|
1c174cc1aa | ||
|
|
3e2a2a76fd | ||
|
|
f91988979f | ||
|
|
c6846565cf | ||
|
|
7962eeef22 | ||
|
|
8cecc50b9d | ||
|
|
075605f304 | ||
|
|
220e2281e4 | ||
|
|
38a0145869 | ||
|
|
432d54900e | ||
|
|
efca5456b8 | ||
|
|
f78f654131 | ||
|
|
99b210d7ea | ||
|
|
e286480e34 | ||
|
|
de44eafd78 | ||
|
|
1e7769dfa3 | ||
|
|
61553ccdda | ||
|
|
d6ec8f668e | ||
|
|
d627083ed5 | ||
|
|
feb26d6c74 | ||
|
|
7c51275bce | ||
|
|
39246f65df | ||
|
|
88552c51ae | ||
|
|
f46811633c | ||
|
|
1ba2c32135 | ||
|
|
37d529f818 | ||
|
|
1d7a46a588 | ||
|
|
4956e3c0a2 | ||
|
|
0cb4484d43 | ||
|
|
f23c45f7f4 | ||
|
|
b96ae6674d | ||
|
|
58a1d7ec30 | ||
|
|
eb4c9ed881 | ||
|
|
9b3472637e | ||
|
|
2b91256c61 | ||
|
|
d22259426c | ||
|
|
823604a4e0 |
23
AUTHORS
@@ -172,4 +172,25 @@ Scott McWhirter <scott.mcwhirter@joyent.com>
|
||||
Jakub Lekstan <jakub.lekstan@dreamlab.pl>
|
||||
Tim Baumann <tim@timbaumann.info>
|
||||
Robert Mustacchi <rm@joyent.com>
|
||||
|
||||
George Miroshnykov <george.miroshnykov@gmail.com>
|
||||
Marcel Laverdet <marcel@laverdet.com>
|
||||
Alexandre Marangone <a.marangone@gmail.com>
|
||||
Mark Cavage <mark.cavage@joyent.com>
|
||||
Ryan Petrello <lists@ryanpetrello.com>
|
||||
Siddharth Mahendraker <siddharth_mahen@hotmail.com>
|
||||
Mathias Buus <m@ge.tt>
|
||||
Yoshihiro KIKUCHI <yknetg@gmail.com>
|
||||
Brett Kiefer <kiefer@gmail.com>
|
||||
Mariano Iglesias <mariano@cricava.com>
|
||||
Jörn Horstmann <git@jhorstmann.net>
|
||||
Joe Shaw <joeshaw@litl.com>
|
||||
Alex Xu <alex_y_xu@yahoo.ca>
|
||||
Kip Gebhardt <kip.gebhardt@voxer.com>
|
||||
Stefan Rusu <saltwaterc@gmail.com>
|
||||
Wojciech Wnętrzak <w.wnetrzak@gmail.com>
|
||||
Reid Burke <me@reidburke.com>
|
||||
Vicente Jimenez Aguilar <googuy@gmail.com>
|
||||
SAWADA Tadashi <cesare@mayverse.jp>
|
||||
Logan Smyth <loganfsmyth@gmail.com>
|
||||
Christopher Wright <christopherwright@gmail.com>
|
||||
Mickaël Delahaye <mickael.delahaye@gmail.com>
|
||||
|
||||
138
ChangeLog
@@ -1,4 +1,114 @@
|
||||
2011.05.20, Version 0.4.8 (stable)
|
||||
2011.09.15, Version 0.4.12 (stable)
|
||||
|
||||
* Improve docs
|
||||
|
||||
* #1563 overflow in ChildProcess custom_fd.
|
||||
|
||||
* #1569, parse error on multi-line HTTP headers. (Ben Noordhuis)
|
||||
|
||||
* #1586 net: Socket write encoding case sensitivity (koichik)
|
||||
|
||||
* #1610 Remove DigiNotar CA from trusted list (isaacs)
|
||||
|
||||
* #1624 buffer: Avoid overrun with 'binary' encoding. (koichik)
|
||||
|
||||
* #1633 buffer: write() should always set _charsWritten. (koichik)
|
||||
|
||||
* #1707 hasOwnProperty usage security hole in querystring (isaacs)
|
||||
|
||||
* #1719 Drain OpenSSL error queue
|
||||
|
||||
* Fix error reporting in net.Server.listen
|
||||
|
||||
|
||||
2011.08.17, Version 0.4.11 (stable), a745d19ce7d1c0e3778371af4f0346be70cf2c8e
|
||||
|
||||
* #738 Fix crypto encryption/decryption with Base64. (SAWADA Tadashi)
|
||||
|
||||
* #1202 net.createConnection defer DNS lookup error events to next tick
|
||||
(Ben Noordhuis)
|
||||
|
||||
* #1374 fix setting ServerResponse.statusCode in writeHead (Trent Mick)
|
||||
|
||||
* #1417 Fix http.ClientRequest crashes if end() was called twice
|
||||
|
||||
* #1497 querystring: Replace 'in' test with 'hasOwnProperty' (isaacs)
|
||||
|
||||
* #1546 http perf improvement
|
||||
|
||||
* fix memleak in libeio (Tom Hughes)
|
||||
|
||||
* cmake improvements (Tom Hughes)
|
||||
|
||||
* node_net.cc: fix incorrect sizeof() (Tom Hughes)
|
||||
|
||||
* Windows/cygwin: no more GetConsoleTitleW errors on XP (Bert Belder)
|
||||
|
||||
* Doc improvments (koichik, Logan Smyth, Ben Noordhuis, Arnout Kazemier)
|
||||
|
||||
|
||||
2011.07.19, Version 0.4.10 (stable), 1b8dd65d6e3b82b6863ef38835cc436c5d30c1d5
|
||||
|
||||
* #394 Fix Buffer drops last null character in UTF-8
|
||||
|
||||
* #829 Backport r8577 from V8 (Ben Noordhuis)
|
||||
|
||||
* #877 Don't wait for HTTP Agent socket pool to establish connections.
|
||||
|
||||
* #915 Find kqueue on FreeBSD correctly (Brett Kiefer)
|
||||
|
||||
* #1085 HTTP: Fix race in abort/dispatch code (Stefan Rusu)
|
||||
|
||||
* #1274 debugger improvement (Yoshihiro Kikuchi)
|
||||
|
||||
* #1291 Properly respond to HEAD during end(body) hot path (Reid Burke)
|
||||
|
||||
* #1304 TLS: Fix race in abort/connection code (Stefan Rusu)
|
||||
|
||||
* #1360 Allow _ in url hostnames.
|
||||
|
||||
* Revert 37d529f8 - unbreaks debugger command parsing.
|
||||
|
||||
* Bring back global execScript
|
||||
|
||||
* Doc improvements
|
||||
|
||||
|
||||
2011.06.29, Version 0.4.9 (stable)
|
||||
|
||||
* Improve documentation
|
||||
|
||||
* #1095 error handling bug in stream.pipe() (Felix Geisendörfer)
|
||||
|
||||
* #1097 Fix a few leaks in node_crypto.cc (Ben Noordhuis)
|
||||
|
||||
* #562 #1078 Parse file:// urls properly (Ryan Petrello)
|
||||
|
||||
* #880 Option to disable SSLv2 (Jérémy Lal)
|
||||
|
||||
* #1087 Disabling SSL compression disabled with early OpenSSLs.
|
||||
|
||||
* #1144 debugger: don't allow users to input non-valid commands
|
||||
(Siddharth Mahendraker)
|
||||
|
||||
* Perf improvement for util.inherits
|
||||
|
||||
* #1166 Support for signature verification with RSA/DSA public keys
|
||||
(Mark Cavage)
|
||||
|
||||
* #1177 Remove node_modules lookup optimization to better support
|
||||
nested project structures (Mathias Buus)
|
||||
|
||||
* #1203 Add missing scope.Close to fs.sendfileSync
|
||||
|
||||
* #1187 Support multiple 'link' headers
|
||||
|
||||
* #1196 Fix -e/--eval can't load module from node_modules (Koichi Kobayashi)
|
||||
|
||||
* Upgrade V8 to 3.1.8.25, upgrade http-parser.
|
||||
|
||||
|
||||
2011.05.20, Version 0.4.8 (stable), 7dd22c26e4365698dc3efddf138c4d399cb912c8
|
||||
|
||||
* #974 Properly report traceless errors (isaacs)
|
||||
|
||||
@@ -67,10 +177,10 @@
|
||||
|
||||
* http response.readable should be false after 'end' #867 (Abe Fettig)
|
||||
|
||||
* Implemenet os.cpus() and os.uptime() on Solaris (Scott McWhirter)
|
||||
* Implement os.cpus() and os.uptime() on Solaris (Scott McWhirter)
|
||||
|
||||
* fs.ReadStream: Allow omission of end option for range reads #801
|
||||
(Felix Geisendörfer)
|
||||
(Felix Geisendörfer)
|
||||
|
||||
* Buffer.write() with UCS-2 should not be write partial char
|
||||
#916 (koichik)
|
||||
@@ -156,11 +266,11 @@
|
||||
* Pragma HTTP header comma separation
|
||||
|
||||
* In addition to 'aborted' emit 'close' from incoming requests
|
||||
(Felix Geisendörfer)
|
||||
(Felix Geisendörfer)
|
||||
|
||||
* Fix memleak in vm.runInNewContext
|
||||
|
||||
* Do not cache modules that throw exceptions (Felix Geisendörfer)
|
||||
* Do not cache modules that throw exceptions (Felix Geisendörfer)
|
||||
|
||||
* Build system changes for libnode (Aria Stewart)
|
||||
|
||||
@@ -178,7 +288,7 @@
|
||||
|
||||
* URL parse more safely (isaacs)
|
||||
|
||||
* Expose errno with a string for dns/cares (Felix Geisendörfer)
|
||||
* Expose errno with a string for dns/cares (Felix Geisendörfer)
|
||||
|
||||
* Fix tty.setWindowSize
|
||||
|
||||
@@ -202,7 +312,7 @@
|
||||
|
||||
* Improve V8 support for Cygwin (Bert Belder)
|
||||
|
||||
* Fix fs.open param parsing. (Felix Geisendörfer)
|
||||
* Fix fs.open param parsing. (Felix Geisendörfer)
|
||||
|
||||
* Fixed null signal.
|
||||
|
||||
@@ -333,12 +443,12 @@
|
||||
* Allow third party hooks before main module load.
|
||||
(See 496be457b6a2bc5b01ec13644b9c9783976159b2)
|
||||
|
||||
* Don't stat() on cached modules. (Felix Geisendörfer)
|
||||
* Don't stat() on cached modules. (Felix Geisendörfer)
|
||||
|
||||
|
||||
2011.01.08, Version 0.3.4 (unstable)
|
||||
|
||||
* Primordal mingw build (Bert Belder)
|
||||
* Primordial mingw build (Bert Belder)
|
||||
|
||||
* HTTPS server
|
||||
|
||||
@@ -368,7 +478,7 @@
|
||||
functions for OSX, Linux, and Cygwin. (Brian White)
|
||||
|
||||
* Fix REPL syntax error bug (GH-543), improve how REPL commands are
|
||||
evaulated.
|
||||
evaluated.
|
||||
|
||||
* Use process.stdin instead of process.openStdin().
|
||||
|
||||
@@ -409,7 +519,7 @@
|
||||
|
||||
2010.11.16, Version 0.3.1 (unstable), ce9a54aa1fbf709dd30316af8a2f14d83150e947
|
||||
|
||||
* TLS improvments (Paul Querna)
|
||||
* TLS improvements (Paul Querna)
|
||||
- Centralize error handling in SecureStream
|
||||
- Add SecurePair for handling of a ssl/tls stream.
|
||||
|
||||
@@ -471,9 +581,9 @@
|
||||
|
||||
2010.10.23, Version 0.3.0 (unstable) 1582cfebd6719b2d2373547994b3dca5c8c569c0
|
||||
|
||||
* Bugfix: Do not spin on aceept() with EMFILE
|
||||
* Bugfix: Do not spin on accept() with EMFILE
|
||||
|
||||
* Improvments to readline.js (Trent Mick, Johan Euphrosine, Brian White)
|
||||
* Improvements to readline.js (Trent Mick, Johan Euphrosine, Brian White)
|
||||
|
||||
* Safe constructors (missing 'new' doesn't segfault)
|
||||
|
||||
@@ -509,7 +619,7 @@
|
||||
|
||||
* Commas last in sys.inspect
|
||||
|
||||
* Constatnts moved from process object to require('constants')
|
||||
* Constants moved from process object to require('constants')
|
||||
|
||||
* Fix parsing of linux memory (Vitali Lovich)
|
||||
|
||||
|
||||
2
Makefile
@@ -1,6 +1,6 @@
|
||||
WAF=python tools/waf-light
|
||||
|
||||
web_root = ryan@nodejs.org:~/web/nodejs.org/
|
||||
web_root = node@nodejs.org:~/web/nodejs.org/
|
||||
|
||||
all: program
|
||||
|
||||
|
||||
@@ -11,26 +11,6 @@ for (var i = 0; i < 20*1024; i++) {
|
||||
fixed += "C";
|
||||
}
|
||||
|
||||
var uname, rev;
|
||||
|
||||
exec('git rev-list -1 HEAD', function (e, stdout) {
|
||||
if (e) {
|
||||
console.error("Problem executing: 'git rev-list -1 HEAD'");
|
||||
throw new Error(e);
|
||||
}
|
||||
rev = stdout.replace(/\s/g, '');
|
||||
});
|
||||
|
||||
exec('uname -a', function (e, stdout) {
|
||||
if (e) {
|
||||
console.error("Problem executing: 'uname -a'");
|
||||
throw new Error(e);
|
||||
}
|
||||
uname = stdout.replace(/[\r\n]/g, '');
|
||||
});
|
||||
|
||||
|
||||
|
||||
stored = {};
|
||||
storedBuffer = {};
|
||||
|
||||
@@ -39,6 +19,7 @@ var server = http.createServer(function (req, res) {
|
||||
var command = commands[1];
|
||||
var body = "";
|
||||
var arg = commands[2];
|
||||
var n_chunks = parseInt(commands[3], 10);
|
||||
var status = 200;
|
||||
|
||||
if (command == "bytes") {
|
||||
@@ -73,19 +54,32 @@ var server = http.createServer(function (req, res) {
|
||||
} else if (command == "fixed") {
|
||||
body = fixed;
|
||||
|
||||
} else if (command == "info") {
|
||||
body = 'rev=' + rev + '\nuname="' + uname + '"\n';
|
||||
|
||||
} else {
|
||||
status = 404;
|
||||
body = "not found\n";
|
||||
}
|
||||
|
||||
var content_length = body.length.toString();
|
||||
// example: http://localhost:port/bytes/512/4
|
||||
// sends a 512 byte body in 4 chunks of 128 bytes
|
||||
if (n_chunks > 0) {
|
||||
res.writeHead(status, { "Content-Type": "text/plain",
|
||||
"Transfer-Encoding": "chunked" });
|
||||
// send body in chunks
|
||||
var len = body.length;
|
||||
var step = ~~(len / n_chunks) || len;
|
||||
|
||||
res.writeHead(status, { "Content-Type": "text/plain",
|
||||
"Content-Length": content_length });
|
||||
res.end(body);
|
||||
for (var i = 0; i < len; i += step) {
|
||||
res.write(body.slice(i, i + step));
|
||||
}
|
||||
|
||||
res.end();
|
||||
} else {
|
||||
var content_length = body.length.toString();
|
||||
|
||||
res.writeHead(status, { "Content-Type": "text/plain",
|
||||
"Content-Length": content_length });
|
||||
res.end(body);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -93,3 +87,6 @@ server.listen(port, function () {
|
||||
console.log('Listening at http://127.0.0.1:'+port+'/');
|
||||
});
|
||||
|
||||
process.on('exit', function() {
|
||||
console.error('libuv counters', process.uvCounters());
|
||||
});
|
||||
|
||||
@@ -33,10 +33,13 @@ if(${node_arch} MATCHES unknown)
|
||||
set(node_arch x86)
|
||||
endif()
|
||||
|
||||
set(NODE_INCLUDE_PREFIX ${CMAKE_INSTALL_PREFIX})
|
||||
|
||||
# Copy tools directory for out-of-source build
|
||||
string(COMPARE EQUAL $(PROJECT_BINARY_DIR) ${PROJECT_SOURCE_DIR} in_source_build)
|
||||
if(NOT ${in_source_build})
|
||||
if(NOT in_source_build)
|
||||
execute_process(COMMAND cmake -E copy_directory ${PROJECT_SOURCE_DIR}/tools ${PROJECT_BINARY_DIR}/tools)
|
||||
configure_file(${PROJECT_SOURCE_DIR}/deps/v8/tools/jsmin.py ${PROJECT_BINARY_DIR}/tools COPYONLY)
|
||||
endif()
|
||||
|
||||
# Set some compiler/linker flags..
|
||||
|
||||
@@ -6,8 +6,8 @@ set(macros_file ${PROJECT_BINARY_DIR}/macros.py)
|
||||
|
||||
# replace debug(x) and assert(x) with nothing in release build
|
||||
if(${CMAKE_BUILD_TYPE} MATCHES Release)
|
||||
file(APPEND ${macros_file} "macro debug(x) = ;\n")
|
||||
file(APPEND ${macros_file} "macro assert(x) = ;\n")
|
||||
file(APPEND ${macros_file} "macro debug(x) = void(0);\n")
|
||||
file(APPEND ${macros_file} "macro assert(x) = void(0);\n")
|
||||
endif()
|
||||
|
||||
if(NOT DTRACE)
|
||||
@@ -21,16 +21,20 @@ if(NOT DTRACE)
|
||||
DTRACE_NET_SOCKET_READ
|
||||
DTRACE_NET_SOCKET_WRITE)
|
||||
foreach(probe ${dtrace_probes})
|
||||
file(APPEND ${macros_file} "macro ${probe}(x) = ;\n")
|
||||
file(APPEND ${macros_file} "macro ${probe}(x) = void(0);\n")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# Sort the JS files being built into natives so that the build is
|
||||
# deterministic
|
||||
list(SORT js2c_files)
|
||||
|
||||
# include macros file in generation
|
||||
set(js2c_files ${js2c_files} ${macros_file})
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_BINARY_DIR}/src/node_natives.h
|
||||
COMMAND ${PYTHON_EXECUTABLE} tools/js2c.py ${PROJECT_BINARY_DIR}/src/node_natives.h ${js2c_files}
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_BINARY_DIR}/tools/js2c.py ${PROJECT_BINARY_DIR}/src/node_natives.h ${js2c_files}
|
||||
DEPENDS ${js2c_files})
|
||||
|
||||
set(node_platform_src "src/platform_${node_platform}.cc")
|
||||
@@ -138,5 +142,5 @@ install(FILES
|
||||
src/node_version.h
|
||||
${PROJECT_BINARY_DIR}/src/node_config.h
|
||||
|
||||
DESTINATION include/node
|
||||
DESTINATION ${NODE_INCLUDE_PREFIX}/include/node
|
||||
)
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
# package
|
||||
#
|
||||
|
||||
# Allow absolute paths when installing
|
||||
# see http://www.cmake.org/pipermail/cmake/2008-July/022958.html
|
||||
set(CPACK_SET_DESTDIR "ON")
|
||||
|
||||
if(${node_platform} MATCHES darwin)
|
||||
set(CPACK_GENERATOR "TGZ;PackageMaker")
|
||||
# CPack requires the files to end in .txt
|
||||
@@ -24,7 +28,7 @@ set(CPACK_PACKAGE_DESCRIPTION "Evented I/O for V8 JavaScript.
|
||||
presents the event loop as a language construct instead of as a library.")
|
||||
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION}")
|
||||
set(CPACK_DEBIAN_PACKAGE_SECTION "web")
|
||||
file(READ ${PROJECT_SOURCE_DIR}/src/node_version.h node_version_h LIMIT 1024 OFFSET 0)
|
||||
file(READ ${PROJECT_SOURCE_DIR}/src/node_version.h node_version_h OFFSET 0)
|
||||
string(REGEX REPLACE ".*NODE_MAJOR_VERSION[ ]*([0-9]+).*" "\\1" CPACK_PACKAGE_VERSION_MAJOR "${node_version_h}")
|
||||
string(REGEX REPLACE ".*NODE_MINOR_VERSION[ ]*([0-9]+).*" "\\1" CPACK_PACKAGE_VERSION_MINOR "${node_version_h}")
|
||||
string(REGEX REPLACE ".*NODE_PATCH_VERSION[ ]*([0-9]+).*" "\\1" CPACK_PACKAGE_VERSION_PATCH "${node_version_h}")
|
||||
|
||||
1
deps/http_parser/.gitignore
vendored
@@ -2,3 +2,4 @@ tags
|
||||
*.o
|
||||
test
|
||||
test_g
|
||||
test_fast
|
||||
|
||||
6
deps/http_parser/LICENSE-MIT
vendored
@@ -1,4 +1,8 @@
|
||||
Copyright 2009,2010 Ryan Dahl <ry@tinyclouds.org>
|
||||
http_parser.c is based on src/http/ngx_http_parse.c from NGINX copyright
|
||||
Igor Sysoev.
|
||||
|
||||
Additional changes are licensed under the same terms as NGINX and
|
||||
copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
|
||||
13
deps/http_parser/Makefile
vendored
@@ -1,11 +1,14 @@
|
||||
OPT_DEBUG=-O0 -g -Wall -Wextra -Werror -I.
|
||||
OPT_FAST=-O3 -DHTTP_PARSER_STRICT=0 -I.
|
||||
CPPFLAGS?=-Wall -Wextra -Werror -I.
|
||||
OPT_DEBUG=$(CPPFLAGS) -O0 -g -DHTTP_PARSER_STRICT=1
|
||||
OPT_FAST=$(CPPFLAGS) -O3 -DHTTP_PARSER_STRICT=0
|
||||
|
||||
CC?=gcc
|
||||
AR?=ar
|
||||
|
||||
|
||||
test: test_g
|
||||
test: test_g test_fast
|
||||
./test_g
|
||||
./test_fast
|
||||
|
||||
test_g: http_parser_g.o test_g.o
|
||||
$(CC) $(OPT_DEBUG) http_parser_g.o test_g.o -o $@
|
||||
@@ -31,11 +34,13 @@ test_fast: http_parser.o test.c http_parser.h
|
||||
test-run-timed: test_fast
|
||||
while(true) do time ./test_fast > /dev/null; done
|
||||
|
||||
package: http_parser.o
|
||||
$(AR) rcs libhttp_parser.a http_parser.o
|
||||
|
||||
tags: http_parser.c http_parser.h test.c
|
||||
ctags $^
|
||||
|
||||
clean:
|
||||
rm -f *.o test test_fast test_g http_parser.tar tags
|
||||
rm -f *.o *.a test test_fast test_g http_parser.tar tags
|
||||
|
||||
.PHONY: clean package test-run test-run-timed test-valgrind
|
||||
|
||||
149
deps/http_parser/http_parser.c
vendored
@@ -1,4 +1,7 @@
|
||||
/* Copyright 2009,2010 Ryan Dahl <ry@tinyclouds.org>
|
||||
/* Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev
|
||||
*
|
||||
* Additional changes are licensed under the same terms as NGINX and
|
||||
* copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
@@ -97,6 +100,7 @@ static const char *method_strings[] =
|
||||
, "NOTIFY"
|
||||
, "SUBSCRIBE"
|
||||
, "UNSUBSCRIBE"
|
||||
, "PATCH"
|
||||
};
|
||||
|
||||
|
||||
@@ -186,7 +190,7 @@ static const uint8_t normal_url_char[256] = {
|
||||
/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */
|
||||
1, 1, 1, 1, 1, 1, 1, 0 };
|
||||
1, 1, 1, 1, 1, 1, 1, 0, };
|
||||
|
||||
|
||||
enum state
|
||||
@@ -237,18 +241,21 @@ enum state
|
||||
, s_header_field
|
||||
, s_header_value_start
|
||||
, s_header_value
|
||||
, s_header_value_lws
|
||||
|
||||
, s_header_almost_done
|
||||
|
||||
, s_chunk_size_start
|
||||
, s_chunk_size
|
||||
, s_chunk_parameters
|
||||
, s_chunk_size_almost_done
|
||||
|
||||
, s_headers_almost_done
|
||||
/* Important: 's_headers_almost_done' must be the last 'header' state. All
|
||||
* states beyond this must be 'body' states. It is used for overflow
|
||||
* checking. See the PARSING_HEADER() macro.
|
||||
*/
|
||||
, s_chunk_size_start
|
||||
, s_chunk_size
|
||||
, s_chunk_size_almost_done
|
||||
, s_chunk_parameters
|
||||
|
||||
, s_chunk_data
|
||||
, s_chunk_data_almost_done
|
||||
, s_chunk_data_done
|
||||
@@ -258,7 +265,7 @@ enum state
|
||||
};
|
||||
|
||||
|
||||
#define PARSING_HEADER(state) (state <= s_headers_almost_done && 0 == (parser->flags & F_TRAILING))
|
||||
#define PARSING_HEADER(state) (state <= s_headers_almost_done)
|
||||
|
||||
|
||||
enum header_states
|
||||
@@ -288,20 +295,24 @@ enum header_states
|
||||
};
|
||||
|
||||
|
||||
enum flags
|
||||
{ F_CHUNKED = 1 << 0
|
||||
, F_CONNECTION_KEEP_ALIVE = 1 << 1
|
||||
, F_CONNECTION_CLOSE = 1 << 2
|
||||
, F_TRAILING = 1 << 3
|
||||
, F_UPGRADE = 1 << 4
|
||||
, F_SKIPBODY = 1 << 5
|
||||
};
|
||||
/* Macros for character classes; depends on strict-mode */
|
||||
#define CR '\r'
|
||||
#define LF '\n'
|
||||
#define LOWER(c) (unsigned char)(c | 0x20)
|
||||
#define TOKEN(c) (tokens[(unsigned char)c])
|
||||
#define IS_ALPHA(c) ((c) >= 'a' && (c) <= 'z')
|
||||
#define IS_NUM(c) ((c) >= '0' && (c) <= '9')
|
||||
#define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_NUM(c))
|
||||
|
||||
|
||||
#define CR '\r'
|
||||
#define LF '\n'
|
||||
#define LOWER(c) (unsigned char)(c | 0x20)
|
||||
#define TOKEN(c) tokens[(unsigned char)c]
|
||||
#if HTTP_PARSER_STRICT
|
||||
#define IS_URL_CHAR(c) (normal_url_char[(unsigned char) (c)])
|
||||
#define IS_HOST_CHAR(c) (IS_ALPHANUM(c) || (c) == '.' || (c) == '-')
|
||||
#else
|
||||
#define IS_URL_CHAR(c) \
|
||||
(normal_url_char[(unsigned char) (c)] || ((c) & 0x80))
|
||||
#define IS_HOST_CHAR(c) \
|
||||
(IS_ALPHANUM(c) || (c) == '.' || (c) == '-' || (c) == '_')
|
||||
#endif
|
||||
|
||||
|
||||
#define start_state (parser->type == HTTP_REQUEST ? s_start_req : s_start_res)
|
||||
@@ -322,6 +333,7 @@ size_t http_parser_execute (http_parser *parser,
|
||||
size_t len)
|
||||
{
|
||||
char c, ch;
|
||||
int8_t unhex_val;
|
||||
const char *p = data, *pe;
|
||||
int64_t to_read;
|
||||
|
||||
@@ -478,7 +490,7 @@ size_t http_parser_execute (http_parser *parser,
|
||||
break;
|
||||
}
|
||||
|
||||
if (ch < '0' || ch > '9') goto error;
|
||||
if (!IS_NUM(ch)) goto error;
|
||||
|
||||
parser->http_major *= 10;
|
||||
parser->http_major += ch - '0';
|
||||
@@ -489,7 +501,7 @@ size_t http_parser_execute (http_parser *parser,
|
||||
|
||||
/* first digit of minor HTTP version */
|
||||
case s_res_first_http_minor:
|
||||
if (ch < '0' || ch > '9') goto error;
|
||||
if (!IS_NUM(ch)) goto error;
|
||||
parser->http_minor = ch - '0';
|
||||
state = s_res_http_minor;
|
||||
break;
|
||||
@@ -502,7 +514,7 @@ size_t http_parser_execute (http_parser *parser,
|
||||
break;
|
||||
}
|
||||
|
||||
if (ch < '0' || ch > '9') goto error;
|
||||
if (!IS_NUM(ch)) goto error;
|
||||
|
||||
parser->http_minor *= 10;
|
||||
parser->http_minor += ch - '0';
|
||||
@@ -513,7 +525,7 @@ size_t http_parser_execute (http_parser *parser,
|
||||
|
||||
case s_res_first_status_code:
|
||||
{
|
||||
if (ch < '0' || ch > '9') {
|
||||
if (!IS_NUM(ch)) {
|
||||
if (ch == ' ') {
|
||||
break;
|
||||
}
|
||||
@@ -526,7 +538,7 @@ size_t http_parser_execute (http_parser *parser,
|
||||
|
||||
case s_res_status_code:
|
||||
{
|
||||
if (ch < '0' || ch > '9') {
|
||||
if (!IS_NUM(ch)) {
|
||||
switch (ch) {
|
||||
case ' ':
|
||||
state = s_res_status;
|
||||
@@ -578,7 +590,7 @@ size_t http_parser_execute (http_parser *parser,
|
||||
|
||||
CALLBACK2(message_begin);
|
||||
|
||||
if (ch < 'A' || 'Z' < ch) goto error;
|
||||
if (!IS_ALPHA(LOWER(ch))) goto error;
|
||||
|
||||
start_req_method_assign:
|
||||
parser->method = (enum http_method) 0;
|
||||
@@ -592,7 +604,9 @@ size_t http_parser_execute (http_parser *parser,
|
||||
case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH */ break;
|
||||
case 'N': parser->method = HTTP_NOTIFY; break;
|
||||
case 'O': parser->method = HTTP_OPTIONS; break;
|
||||
case 'P': parser->method = HTTP_POST; /* or PROPFIND or PROPPATCH or PUT */ break;
|
||||
case 'P': parser->method = HTTP_POST;
|
||||
/* or PROPFIND or PROPPATCH or PUT or PATCH */
|
||||
break;
|
||||
case 'R': parser->method = HTTP_REPORT; break;
|
||||
case 'S': parser->method = HTTP_SUBSCRIBE; break;
|
||||
case 'T': parser->method = HTTP_TRACE; break;
|
||||
@@ -633,6 +647,8 @@ size_t http_parser_execute (http_parser *parser,
|
||||
parser->method = HTTP_PROPFIND; /* or HTTP_PROPPATCH */
|
||||
} else if (index == 1 && parser->method == HTTP_POST && ch == 'U') {
|
||||
parser->method = HTTP_PUT;
|
||||
} else if (index == 1 && parser->method == HTTP_POST && ch == 'A') {
|
||||
parser->method = HTTP_PATCH;
|
||||
} else if (index == 2 && parser->method == HTTP_UNLOCK && ch == 'S') {
|
||||
parser->method = HTTP_UNSUBSCRIBE;
|
||||
} else if (index == 4 && parser->method == HTTP_PROPFIND && ch == 'P') {
|
||||
@@ -657,9 +673,13 @@ size_t http_parser_execute (http_parser *parser,
|
||||
|
||||
c = LOWER(ch);
|
||||
|
||||
if (c >= 'a' && c <= 'z') {
|
||||
/* Proxied requests are followed by scheme of an absolute URI (alpha).
|
||||
* CONNECT is followed by a hostname, which begins with alphanum.
|
||||
* All other methods are followed by '/' or '*' (handled above).
|
||||
*/
|
||||
if (IS_ALPHA(ch) || (parser->method == HTTP_CONNECT && IS_NUM(ch))) {
|
||||
MARK(url);
|
||||
state = s_req_schema;
|
||||
state = (parser->method == HTTP_CONNECT) ? s_req_host : s_req_schema;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -670,17 +690,11 @@ size_t http_parser_execute (http_parser *parser,
|
||||
{
|
||||
c = LOWER(ch);
|
||||
|
||||
if (c >= 'a' && c <= 'z') break;
|
||||
if (IS_ALPHA(c)) break;
|
||||
|
||||
if (ch == ':') {
|
||||
state = s_req_schema_slash;
|
||||
break;
|
||||
} else if (ch == '.') {
|
||||
state = s_req_host;
|
||||
break;
|
||||
} else if ('0' <= ch && ch <= '9') {
|
||||
state = s_req_host;
|
||||
break;
|
||||
}
|
||||
|
||||
goto error;
|
||||
@@ -699,8 +713,7 @@ size_t http_parser_execute (http_parser *parser,
|
||||
case s_req_host:
|
||||
{
|
||||
c = LOWER(ch);
|
||||
if (c >= 'a' && c <= 'z') break;
|
||||
if ((ch >= '0' && ch <= '9') || ch == '.' || ch == '-') break;
|
||||
if (IS_HOST_CHAR(ch)) break;
|
||||
switch (ch) {
|
||||
case ':':
|
||||
state = s_req_port;
|
||||
@@ -717,6 +730,9 @@ size_t http_parser_execute (http_parser *parser,
|
||||
CALLBACK(url);
|
||||
state = s_req_http_start;
|
||||
break;
|
||||
case '?':
|
||||
state = s_req_query_string_start;
|
||||
break;
|
||||
default:
|
||||
goto error;
|
||||
}
|
||||
@@ -725,7 +741,7 @@ size_t http_parser_execute (http_parser *parser,
|
||||
|
||||
case s_req_port:
|
||||
{
|
||||
if (ch >= '0' && ch <= '9') break;
|
||||
if (IS_NUM(ch)) break;
|
||||
switch (ch) {
|
||||
case '/':
|
||||
MARK(path);
|
||||
@@ -739,6 +755,9 @@ size_t http_parser_execute (http_parser *parser,
|
||||
CALLBACK(url);
|
||||
state = s_req_http_start;
|
||||
break;
|
||||
case '?':
|
||||
state = s_req_query_string_start;
|
||||
break;
|
||||
default:
|
||||
goto error;
|
||||
}
|
||||
@@ -747,7 +766,7 @@ size_t http_parser_execute (http_parser *parser,
|
||||
|
||||
case s_req_path:
|
||||
{
|
||||
if (normal_url_char[(unsigned char)ch]) break;
|
||||
if (IS_URL_CHAR(ch)) break;
|
||||
|
||||
switch (ch) {
|
||||
case ' ':
|
||||
@@ -785,7 +804,7 @@ size_t http_parser_execute (http_parser *parser,
|
||||
|
||||
case s_req_query_string_start:
|
||||
{
|
||||
if (normal_url_char[(unsigned char)ch]) {
|
||||
if (IS_URL_CHAR(ch)) {
|
||||
MARK(query_string);
|
||||
state = s_req_query_string;
|
||||
break;
|
||||
@@ -821,7 +840,7 @@ size_t http_parser_execute (http_parser *parser,
|
||||
|
||||
case s_req_query_string:
|
||||
{
|
||||
if (normal_url_char[(unsigned char)ch]) break;
|
||||
if (IS_URL_CHAR(ch)) break;
|
||||
|
||||
switch (ch) {
|
||||
case '?':
|
||||
@@ -858,7 +877,7 @@ size_t http_parser_execute (http_parser *parser,
|
||||
|
||||
case s_req_fragment_start:
|
||||
{
|
||||
if (normal_url_char[(unsigned char)ch]) {
|
||||
if (IS_URL_CHAR(ch)) {
|
||||
MARK(fragment);
|
||||
state = s_req_fragment;
|
||||
break;
|
||||
@@ -895,7 +914,7 @@ size_t http_parser_execute (http_parser *parser,
|
||||
|
||||
case s_req_fragment:
|
||||
{
|
||||
if (normal_url_char[(unsigned char)ch]) break;
|
||||
if (IS_URL_CHAR(ch)) break;
|
||||
|
||||
switch (ch) {
|
||||
case ' ':
|
||||
@@ -973,7 +992,7 @@ size_t http_parser_execute (http_parser *parser,
|
||||
break;
|
||||
}
|
||||
|
||||
if (ch < '0' || ch > '9') goto error;
|
||||
if (!IS_NUM(ch)) goto error;
|
||||
|
||||
parser->http_major *= 10;
|
||||
parser->http_major += ch - '0';
|
||||
@@ -984,7 +1003,7 @@ size_t http_parser_execute (http_parser *parser,
|
||||
|
||||
/* first digit of minor HTTP version */
|
||||
case s_req_first_http_minor:
|
||||
if (ch < '0' || ch > '9') goto error;
|
||||
if (!IS_NUM(ch)) goto error;
|
||||
parser->http_minor = ch - '0';
|
||||
state = s_req_http_minor;
|
||||
break;
|
||||
@@ -1004,7 +1023,7 @@ size_t http_parser_execute (http_parser *parser,
|
||||
|
||||
/* XXX allow spaces after digit? */
|
||||
|
||||
if (ch < '0' || ch > '9') goto error;
|
||||
if (!IS_NUM(ch)) goto error;
|
||||
|
||||
parser->http_minor *= 10;
|
||||
parser->http_minor += ch - '0';
|
||||
@@ -1022,6 +1041,7 @@ size_t http_parser_execute (http_parser *parser,
|
||||
}
|
||||
|
||||
case s_header_field_start:
|
||||
header_field_start:
|
||||
{
|
||||
if (ch == CR) {
|
||||
state = s_headers_almost_done;
|
||||
@@ -1199,7 +1219,7 @@ size_t http_parser_execute (http_parser *parser,
|
||||
|
||||
case s_header_value_start:
|
||||
{
|
||||
if (ch == ' ') break;
|
||||
if (ch == ' ' || ch == '\t') break;
|
||||
|
||||
MARK(header_value);
|
||||
|
||||
@@ -1237,7 +1257,7 @@ size_t http_parser_execute (http_parser *parser,
|
||||
break;
|
||||
|
||||
case h_content_length:
|
||||
if (ch < '0' || ch > '9') goto error;
|
||||
if (!IS_NUM(ch)) goto error;
|
||||
parser->content_length = ch - '0';
|
||||
break;
|
||||
|
||||
@@ -1286,7 +1306,7 @@ size_t http_parser_execute (http_parser *parser,
|
||||
|
||||
case h_content_length:
|
||||
if (ch == ' ') break;
|
||||
if (ch < '0' || ch > '9') goto error;
|
||||
if (!IS_NUM(ch)) goto error;
|
||||
parser->content_length *= 10;
|
||||
parser->content_length += ch - '0';
|
||||
break;
|
||||
@@ -1342,7 +1362,7 @@ size_t http_parser_execute (http_parser *parser,
|
||||
{
|
||||
STRICT_CHECK(ch != LF);
|
||||
|
||||
state = s_header_field_start;
|
||||
state = s_header_value_lws;
|
||||
|
||||
switch (header_state) {
|
||||
case h_connection_keep_alive:
|
||||
@@ -1360,6 +1380,18 @@ size_t http_parser_execute (http_parser *parser,
|
||||
break;
|
||||
}
|
||||
|
||||
case s_header_value_lws:
|
||||
{
|
||||
if (ch == ' ' || ch == '\t')
|
||||
state = s_header_value_start;
|
||||
else
|
||||
{
|
||||
state = s_header_field_start;
|
||||
goto header_field_start;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case s_headers_almost_done:
|
||||
headers_almost_done:
|
||||
{
|
||||
@@ -1458,11 +1490,12 @@ size_t http_parser_execute (http_parser *parser,
|
||||
|
||||
case s_chunk_size_start:
|
||||
{
|
||||
assert(nread == 1);
|
||||
assert(parser->flags & F_CHUNKED);
|
||||
|
||||
c = unhex[(unsigned char)ch];
|
||||
if (c == -1) goto error;
|
||||
parser->content_length = c;
|
||||
unhex_val = unhex[(unsigned char)ch];
|
||||
if (unhex_val == -1) goto error;
|
||||
parser->content_length = unhex_val;
|
||||
state = s_chunk_size;
|
||||
break;
|
||||
}
|
||||
@@ -1476,9 +1509,9 @@ size_t http_parser_execute (http_parser *parser,
|
||||
break;
|
||||
}
|
||||
|
||||
c = unhex[(unsigned char)ch];
|
||||
unhex_val = unhex[(unsigned char)ch];
|
||||
|
||||
if (c == -1) {
|
||||
if (unhex_val == -1) {
|
||||
if (ch == ';' || ch == ' ') {
|
||||
state = s_chunk_parameters;
|
||||
break;
|
||||
@@ -1487,7 +1520,7 @@ size_t http_parser_execute (http_parser *parser,
|
||||
}
|
||||
|
||||
parser->content_length *= 16;
|
||||
parser->content_length += c;
|
||||
parser->content_length += unhex_val;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1507,6 +1540,8 @@ size_t http_parser_execute (http_parser *parser,
|
||||
assert(parser->flags & F_CHUNKED);
|
||||
STRICT_CHECK(ch != LF);
|
||||
|
||||
nread = 0;
|
||||
|
||||
if (parser->content_length == 0) {
|
||||
parser->flags |= F_TRAILING;
|
||||
state = s_header_field_start;
|
||||
|
||||
21
deps/http_parser/http_parser.h
vendored
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2009,2010 Ryan Dahl <ry@tinyclouds.org>
|
||||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
@@ -24,6 +24,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define HTTP_PARSER_VERSION_MAJOR 1
|
||||
#define HTTP_PARSER_VERSION_MINOR 0
|
||||
|
||||
#include <sys/types.h>
|
||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||
@@ -47,8 +49,6 @@ typedef int ssize_t;
|
||||
*/
|
||||
#ifndef HTTP_PARSER_STRICT
|
||||
# define HTTP_PARSER_STRICT 1
|
||||
#else
|
||||
# define HTTP_PARSER_STRICT 0
|
||||
#endif
|
||||
|
||||
|
||||
@@ -106,16 +106,29 @@ enum http_method
|
||||
, HTTP_NOTIFY
|
||||
, HTTP_SUBSCRIBE
|
||||
, HTTP_UNSUBSCRIBE
|
||||
/* RFC-5789 */
|
||||
, HTTP_PATCH
|
||||
};
|
||||
|
||||
|
||||
enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH };
|
||||
|
||||
|
||||
/* Flag values for http_parser.flags field */
|
||||
enum flags
|
||||
{ F_CHUNKED = 1 << 0
|
||||
, F_CONNECTION_KEEP_ALIVE = 1 << 1
|
||||
, F_CONNECTION_CLOSE = 1 << 2
|
||||
, F_TRAILING = 1 << 3
|
||||
, F_UPGRADE = 1 << 4
|
||||
, F_SKIPBODY = 1 << 5
|
||||
};
|
||||
|
||||
|
||||
struct http_parser {
|
||||
/** PRIVATE **/
|
||||
unsigned char type : 2;
|
||||
unsigned char flags : 6;
|
||||
unsigned char flags : 6; /* F_* values from 'flags' enum; semi-public */
|
||||
unsigned char state;
|
||||
unsigned char header_state;
|
||||
unsigned char index;
|
||||
|
||||
172
deps/http_parser/test.c
vendored
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2009,2010 Ryan Dahl <ry@tinyclouds.org>
|
||||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
@@ -498,7 +498,7 @@ const struct message requests[] =
|
||||
#define CONNECT_REQUEST 17
|
||||
, {.name = "connect request"
|
||||
,.type= HTTP_REQUEST
|
||||
,.raw= "CONNECT home0.netscape.com:443 HTTP/1.0\r\n"
|
||||
,.raw= "CONNECT 0-home0.netscape.com:443 HTTP/1.0\r\n"
|
||||
"User-agent: Mozilla/1.1N\r\n"
|
||||
"Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n"
|
||||
"\r\n"
|
||||
@@ -510,7 +510,7 @@ const struct message requests[] =
|
||||
,.query_string= ""
|
||||
,.fragment= ""
|
||||
,.request_path= ""
|
||||
,.request_url= "home0.netscape.com:443"
|
||||
,.request_url= "0-home0.netscape.com:443"
|
||||
,.num_headers= 2
|
||||
,.upgrade=1
|
||||
,.headers= { { "User-agent", "Mozilla/1.1N" }
|
||||
@@ -557,7 +557,7 @@ const struct message requests[] =
|
||||
,.body= ""
|
||||
}
|
||||
|
||||
#define MSEARCH_REQ 19
|
||||
#define MSEARCH_REQ 20
|
||||
, {.name= "m-search request"
|
||||
,.type= HTTP_REQUEST
|
||||
,.raw= "M-SEARCH * HTTP/1.1\r\n"
|
||||
@@ -582,6 +582,168 @@ const struct message requests[] =
|
||||
,.body= ""
|
||||
}
|
||||
|
||||
#define LINE_FOLDING_IN_HEADER 20
|
||||
, {.name= "line folding in header value"
|
||||
,.type= HTTP_REQUEST
|
||||
,.raw= "GET / HTTP/1.1\r\n"
|
||||
"Line1: abc\r\n"
|
||||
"\tdef\r\n"
|
||||
" ghi\r\n"
|
||||
"\t\tjkl\r\n"
|
||||
" mno \r\n"
|
||||
"\t \tqrs\r\n"
|
||||
"Line2: \t line2\t\r\n"
|
||||
"\r\n"
|
||||
,.should_keep_alive= TRUE
|
||||
,.message_complete_on_eof= FALSE
|
||||
,.http_major= 1
|
||||
,.http_minor= 1
|
||||
,.method= HTTP_GET
|
||||
,.query_string= ""
|
||||
,.fragment= ""
|
||||
,.request_path= "/"
|
||||
,.request_url= "/"
|
||||
,.num_headers= 2
|
||||
,.headers= { { "Line1", "abcdefghijklmno qrs" }
|
||||
, { "Line2", "line2\t" }
|
||||
}
|
||||
,.body= ""
|
||||
}
|
||||
|
||||
|
||||
#define QUERY_TERMINATED_HOST 21
|
||||
, {.name= "host terminated by a query string"
|
||||
,.type= HTTP_REQUEST
|
||||
,.raw= "GET http://hypnotoad.org?hail=all HTTP/1.1\r\n"
|
||||
"\r\n"
|
||||
,.should_keep_alive= TRUE
|
||||
,.message_complete_on_eof= FALSE
|
||||
,.http_major= 1
|
||||
,.http_minor= 1
|
||||
,.method= HTTP_GET
|
||||
,.query_string= "hail=all"
|
||||
,.fragment= ""
|
||||
,.request_path= ""
|
||||
,.request_url= "http://hypnotoad.org?hail=all"
|
||||
,.num_headers= 0
|
||||
,.headers= { }
|
||||
,.body= ""
|
||||
}
|
||||
|
||||
#define QUERY_TERMINATED_HOSTPORT 22
|
||||
, {.name= "host:port terminated by a query string"
|
||||
,.type= HTTP_REQUEST
|
||||
,.raw= "GET http://hypnotoad.org:1234?hail=all HTTP/1.1\r\n"
|
||||
"\r\n"
|
||||
,.should_keep_alive= TRUE
|
||||
,.message_complete_on_eof= FALSE
|
||||
,.http_major= 1
|
||||
,.http_minor= 1
|
||||
,.method= HTTP_GET
|
||||
,.query_string= "hail=all"
|
||||
,.fragment= ""
|
||||
,.request_path= ""
|
||||
,.request_url= "http://hypnotoad.org:1234?hail=all"
|
||||
,.num_headers= 0
|
||||
,.headers= { }
|
||||
,.body= ""
|
||||
}
|
||||
|
||||
#define SPACE_TERMINATED_HOSTPORT 23
|
||||
, {.name= "host:port terminated by a space"
|
||||
,.type= HTTP_REQUEST
|
||||
,.raw= "GET http://hypnotoad.org:1234 HTTP/1.1\r\n"
|
||||
"\r\n"
|
||||
,.should_keep_alive= TRUE
|
||||
,.message_complete_on_eof= FALSE
|
||||
,.http_major= 1
|
||||
,.http_minor= 1
|
||||
,.method= HTTP_GET
|
||||
,.query_string= ""
|
||||
,.fragment= ""
|
||||
,.request_path= ""
|
||||
,.request_url= "http://hypnotoad.org:1234"
|
||||
,.num_headers= 0
|
||||
,.headers= { }
|
||||
,.body= ""
|
||||
}
|
||||
|
||||
#if !HTTP_PARSER_STRICT
|
||||
#define UTF8_PATH_REQ 24
|
||||
, {.name= "utf-8 path request"
|
||||
,.type= HTTP_REQUEST
|
||||
,.raw= "GET /δ¶/δt/pope?q=1#narf HTTP/1.1\r\n"
|
||||
"Host: github.com\r\n"
|
||||
"\r\n"
|
||||
,.should_keep_alive= TRUE
|
||||
,.message_complete_on_eof= FALSE
|
||||
,.http_major= 1
|
||||
,.http_minor= 1
|
||||
,.method= HTTP_GET
|
||||
,.query_string= "q=1"
|
||||
,.fragment= "narf"
|
||||
,.request_path= "/δ¶/δt/pope"
|
||||
,.request_url= "/δ¶/δt/pope?q=1#narf"
|
||||
,.num_headers= 1
|
||||
,.headers= { {"Host", "github.com" }
|
||||
}
|
||||
,.body= ""
|
||||
}
|
||||
|
||||
#define HOSTNAME_UNDERSCORE 25
|
||||
, {.name = "hostname underscore"
|
||||
,.type= HTTP_REQUEST
|
||||
,.raw= "CONNECT home_0.netscape.com:443 HTTP/1.0\r\n"
|
||||
"User-agent: Mozilla/1.1N\r\n"
|
||||
"Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n"
|
||||
"\r\n"
|
||||
,.should_keep_alive= FALSE
|
||||
,.message_complete_on_eof= FALSE
|
||||
,.http_major= 1
|
||||
,.http_minor= 0
|
||||
,.method= HTTP_CONNECT
|
||||
,.query_string= ""
|
||||
,.fragment= ""
|
||||
,.request_path= ""
|
||||
,.request_url= "home_0.netscape.com:443"
|
||||
,.num_headers= 2
|
||||
,.upgrade=1
|
||||
,.headers= { { "User-agent", "Mozilla/1.1N" }
|
||||
, { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" }
|
||||
}
|
||||
,.body= ""
|
||||
}
|
||||
#endif /* !HTTP_PARSER_STRICT */
|
||||
|
||||
#define PATCH_REQ 26
|
||||
, {.name = "PATCH request"
|
||||
,.type= HTTP_REQUEST
|
||||
,.raw= "PATCH /file.txt HTTP/1.1\r\n"
|
||||
"Host: www.example.com\r\n"
|
||||
"Content-Type: application/example\r\n"
|
||||
"If-Match: \"e0023aa4e\"\r\n"
|
||||
"Content-Length: 10\r\n"
|
||||
"\r\n"
|
||||
"cccccccccc"
|
||||
,.should_keep_alive= TRUE
|
||||
,.message_complete_on_eof= FALSE
|
||||
,.http_major= 1
|
||||
,.http_minor= 1
|
||||
,.method= HTTP_PATCH
|
||||
,.query_string= ""
|
||||
,.fragment= ""
|
||||
,.request_path= "/file.txt"
|
||||
,.request_url= "/file.txt"
|
||||
,.num_headers= 4
|
||||
,.upgrade=0
|
||||
,.headers= { { "Host", "www.example.com" }
|
||||
, { "Content-Type", "application/example" }
|
||||
, { "If-Match", "\"e0023aa4e\"" }
|
||||
, { "Content-Length", "10" }
|
||||
}
|
||||
,.body= "cccccccccc"
|
||||
}
|
||||
|
||||
, {.name= NULL } /* sentinel */
|
||||
};
|
||||
|
||||
@@ -1810,7 +1972,7 @@ main (void)
|
||||
"\tRA==\r\n"
|
||||
"\t-----END CERTIFICATE-----\r\n"
|
||||
"\r\n";
|
||||
test_simple(dumbfuck2, 0);
|
||||
test_simple(dumbfuck2, 1);
|
||||
|
||||
#if 0
|
||||
// NOTE(Wed Nov 18 11:57:27 CET 2009) this seems okay. we just read body
|
||||
|
||||
4
deps/libeio/eio.c
vendored
@@ -1265,6 +1265,10 @@ eio__scandir (eio_req *req, etp_worker *self)
|
||||
X_LOCK (wrklock);
|
||||
/* the corresponding closedir is in ETP_WORKER_CLEAR */
|
||||
self->dirp = dirp = opendir (req->ptr1);
|
||||
|
||||
if (req->flags & EIO_FLAG_PTR1_FREE)
|
||||
free (req->ptr1);
|
||||
|
||||
req->flags |= EIO_FLAG_PTR1_FREE | EIO_FLAG_PTR2_FREE;
|
||||
req->ptr1 = dents = flags ? malloc (dentalloc * sizeof (eio_dirent)) : 0;
|
||||
req->ptr2 = names = malloc (namesalloc);
|
||||
|
||||
4
deps/libeio/eio.h
vendored
@@ -176,7 +176,7 @@ enum
|
||||
enum
|
||||
{
|
||||
EIO_MCL_CURRENT = 1,
|
||||
EIO_MCL_FUTURE = 2,
|
||||
EIO_MCL_FUTURE = 2
|
||||
};
|
||||
|
||||
/* request priorities */
|
||||
@@ -184,7 +184,7 @@ enum
|
||||
enum {
|
||||
EIO_PRI_MIN = -4,
|
||||
EIO_PRI_MAX = 4,
|
||||
EIO_PRI_DEFAULT = 0,
|
||||
EIO_PRI_DEFAULT = 0
|
||||
};
|
||||
|
||||
/* eio request structure */
|
||||
|
||||
19
deps/libev/wscript
vendored
@@ -28,12 +28,17 @@ def configure(conf):
|
||||
if conf.check_cc(header_name="poll.h"):
|
||||
conf.check_cc(header_name="poll.h", function_name="poll")
|
||||
|
||||
conf.check_cc(header_name="sys/event.h")
|
||||
conf.check_cc(header_name="sys/queue.h")
|
||||
if PLATFORM_IS_DARWIN:
|
||||
conf.check_cc(header_name="sys/event.h", function_name="kqueue")
|
||||
else:
|
||||
conf.check_cc(header_name="sys/queue.h", function_name="kqueue")
|
||||
kqueue_headers = []
|
||||
# On FreeBSD event.h is not selfcontained and requires types.h
|
||||
event_headers = ["sys/types.h", "sys/event.h"]
|
||||
if conf.check_cc(header_name=event_headers, define_name="HAVE_SYS_EVENT_H"):
|
||||
kqueue_headers += event_headers
|
||||
|
||||
if conf.check_cc(header_name="sys/queue.h"):
|
||||
kqueue_headers.append("sys/queue.h")
|
||||
|
||||
if kqueue_headers:
|
||||
conf.check_cc(header_name=kqueue_headers, function_name="kqueue")
|
||||
|
||||
if PLATFORM_IS_WIN32:
|
||||
# Windows has sys/select.h and select but this config line doesn't detect it properly
|
||||
@@ -58,7 +63,7 @@ def configure(conf):
|
||||
return 0;
|
||||
}
|
||||
"""
|
||||
conf.check_cc(fragment=code, define_name="HAVE_CLOCK_SYSCALL", execute=True,
|
||||
conf.check_cc(fragment=code, define_name="HAVE_CLOCK_SYSCALL",
|
||||
msg="Checking for SYS_clock_gettime")
|
||||
|
||||
have_librt = conf.check(lib='rt', uselib_store='RT')
|
||||
|
||||
3
deps/v8/src/arm/codegen-arm.cc
vendored
@@ -7233,6 +7233,9 @@ void CodeGenerator::EmitKeyedStore(StaticType* key_type,
|
||||
|
||||
ASSERT(we_remembered_the_write_barrier);
|
||||
|
||||
// Make sure that r0 holds the value which is the result of the expression.
|
||||
__ Move(r0, value);
|
||||
|
||||
deferred->BindExit();
|
||||
} else {
|
||||
frame()->CallKeyedStoreIC(strict_mode_flag());
|
||||
|
||||
4
deps/v8/src/arm/lithium-arm.cc
vendored
@@ -1936,6 +1936,10 @@ LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
|
||||
|
||||
LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
|
||||
int spill_index = chunk()->GetNextSpillIndex(false); // Not double-width.
|
||||
if (spill_index > LUnallocated::kMaxFixedIndex) {
|
||||
Abort("Too many spill slots needed for OSR");
|
||||
spill_index = 0;
|
||||
}
|
||||
return DefineAsSpilled(new LUnknownOSRValue, spill_index);
|
||||
}
|
||||
|
||||
|
||||
3
deps/v8/src/builtins.cc
vendored
@@ -373,8 +373,7 @@ static bool ArrayPrototypeHasNoElements(Context* global_context,
|
||||
array_proto = JSObject::cast(proto);
|
||||
if (array_proto != global_context->initial_object_prototype()) return false;
|
||||
if (array_proto->elements() != Heap::empty_fixed_array()) return false;
|
||||
ASSERT(array_proto->GetPrototype()->IsNull());
|
||||
return true;
|
||||
return array_proto->GetPrototype()->IsNull();
|
||||
}
|
||||
|
||||
|
||||
|
||||
10
deps/v8/src/compiler.cc
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2010 the V8 project authors. All rights reserved.
|
||||
// Copyright 2011 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
@@ -223,10 +223,12 @@ static bool MakeCrankshaftCode(CompilationInfo* info) {
|
||||
//
|
||||
// The encoding is as a signed value, with parameters and receiver using
|
||||
// the negative indices and locals the non-negative ones.
|
||||
const int limit = LUnallocated::kMaxFixedIndices / 2;
|
||||
const int parameter_limit = -LUnallocated::kMinFixedIndex;
|
||||
const int locals_limit = LUnallocated::kMaxFixedIndex;
|
||||
Scope* scope = info->scope();
|
||||
if ((scope->num_parameters() + 1) > limit ||
|
||||
scope->num_stack_slots() > limit) {
|
||||
if ((scope->num_parameters() + 1) > parameter_limit ||
|
||||
(info->osr_ast_id() != AstNode::kNoNumber &&
|
||||
scope->num_parameters() + 1 + scope->num_stack_slots() > locals_limit)) {
|
||||
AbortAndDisable(info);
|
||||
// True indicates the compilation pipeline is still going, not
|
||||
// necessarily that we optimized the code.
|
||||
|
||||
22
deps/v8/src/hydrogen-instructions.h
vendored
@@ -789,15 +789,33 @@ class HBlockEntry: public HTemplateInstruction<0> {
|
||||
};
|
||||
|
||||
|
||||
class HDeoptimize: public HTemplateControlInstruction<0> {
|
||||
class HDeoptimize: public HControlInstruction {
|
||||
public:
|
||||
HDeoptimize() : HTemplateControlInstruction<0>(NULL, NULL) { }
|
||||
explicit HDeoptimize(int environment_length)
|
||||
: HControlInstruction(NULL, NULL),
|
||||
values_(environment_length) { }
|
||||
|
||||
virtual Representation RequiredInputRepresentation(int index) const {
|
||||
return Representation::None();
|
||||
}
|
||||
|
||||
virtual int OperandCount() { return values_.length(); }
|
||||
virtual HValue* OperandAt(int index) { return values_[index]; }
|
||||
|
||||
void AddEnvironmentValue(HValue* value) {
|
||||
values_.Add(NULL);
|
||||
SetOperandAt(values_.length() - 1, value);
|
||||
}
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
|
||||
|
||||
protected:
|
||||
virtual void InternalSetOperandAt(int index, HValue* value) {
|
||||
values_[index] = value;
|
||||
}
|
||||
|
||||
private:
|
||||
ZoneList<HValue*> values_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
23
deps/v8/src/hydrogen.cc
vendored
@@ -113,6 +113,21 @@ void HBasicBlock::AddInstruction(HInstruction* instr) {
|
||||
}
|
||||
|
||||
|
||||
HDeoptimize* HBasicBlock::CreateDeoptimize() {
|
||||
ASSERT(HasEnvironment());
|
||||
HEnvironment* environment = last_environment();
|
||||
|
||||
HDeoptimize* instr = new HDeoptimize(environment->length());
|
||||
|
||||
for (int i = 0; i < environment->length(); i++) {
|
||||
HValue* val = environment->values()->at(i);
|
||||
instr->AddEnvironmentValue(val);
|
||||
}
|
||||
|
||||
return instr;
|
||||
}
|
||||
|
||||
|
||||
HSimulate* HBasicBlock::CreateSimulate(int id) {
|
||||
ASSERT(HasEnvironment());
|
||||
HEnvironment* environment = last_environment();
|
||||
@@ -2560,7 +2575,7 @@ void HGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
|
||||
// If we have a non-smi compare clause, we deoptimize after trying
|
||||
// all the previous compares.
|
||||
if (num_smi_clauses < num_clauses) {
|
||||
last_false_block->Finish(new HDeoptimize);
|
||||
last_false_block->FinishExitWithDeoptimization();
|
||||
}
|
||||
|
||||
// Build statement blocks, connect them to their comparison block and
|
||||
@@ -3230,7 +3245,7 @@ void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr,
|
||||
HSubgraph* default_graph = CreateBranchSubgraph(environment());
|
||||
{ SubgraphScope scope(this, default_graph);
|
||||
if (!needs_generic && FLAG_deoptimize_uncommon_cases) {
|
||||
default_graph->exit_block()->FinishExit(new HDeoptimize());
|
||||
default_graph->exit_block()->FinishExitWithDeoptimization();
|
||||
default_graph->set_exit_block(NULL);
|
||||
} else {
|
||||
HInstruction* instr = BuildStoreNamedGeneric(object, name, value);
|
||||
@@ -3567,7 +3582,7 @@ void HGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr,
|
||||
HSubgraph* default_graph = CreateBranchSubgraph(environment());
|
||||
{ SubgraphScope scope(this, default_graph);
|
||||
if (!needs_generic && FLAG_deoptimize_uncommon_cases) {
|
||||
default_graph->exit_block()->FinishExit(new HDeoptimize());
|
||||
default_graph->exit_block()->FinishExitWithDeoptimization();
|
||||
default_graph->set_exit_block(NULL);
|
||||
} else {
|
||||
HInstruction* instr = BuildLoadNamedGeneric(object, expr);
|
||||
@@ -3928,7 +3943,7 @@ void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr,
|
||||
HSubgraph* default_graph = CreateBranchSubgraph(environment());
|
||||
{ SubgraphScope scope(this, default_graph);
|
||||
if (!needs_generic && FLAG_deoptimize_uncommon_cases) {
|
||||
default_graph->exit_block()->FinishExit(new HDeoptimize());
|
||||
default_graph->exit_block()->FinishExitWithDeoptimization();
|
||||
default_graph->set_exit_block(NULL);
|
||||
} else {
|
||||
HContext* context = new HContext;
|
||||
|
||||
5
deps/v8/src/hydrogen.h
vendored
@@ -124,6 +124,10 @@ class HBasicBlock: public ZoneObject {
|
||||
void AddSimulate(int id) { AddInstruction(CreateSimulate(id)); }
|
||||
void AssignCommonDominator(HBasicBlock* other);
|
||||
|
||||
void FinishExitWithDeoptimization() {
|
||||
FinishExit(CreateDeoptimize());
|
||||
}
|
||||
|
||||
// Add the inlined function exit sequence, adding an HLeaveInlined
|
||||
// instruction and updating the bailout environment.
|
||||
void AddLeaveInlined(HValue* return_value, HBasicBlock* target);
|
||||
@@ -146,6 +150,7 @@ class HBasicBlock: public ZoneObject {
|
||||
void AddDominatedBlock(HBasicBlock* block);
|
||||
|
||||
HSimulate* CreateSimulate(int id);
|
||||
HDeoptimize* CreateDeoptimize();
|
||||
|
||||
int block_id_;
|
||||
HGraph* graph_;
|
||||
|
||||
8
deps/v8/src/ia32/full-codegen-ia32.cc
vendored
@@ -2772,8 +2772,12 @@ void FullCodeGenerator::EmitMathPow(ZoneList<Expression*>* args) {
|
||||
VisitForStackValue(args->at(0));
|
||||
VisitForStackValue(args->at(1));
|
||||
|
||||
MathPowStub stub;
|
||||
__ CallStub(&stub);
|
||||
if (CpuFeatures::IsSupported(SSE2)) {
|
||||
MathPowStub stub;
|
||||
__ CallStub(&stub);
|
||||
} else {
|
||||
__ CallRuntime(Runtime::kMath_pow, 2);
|
||||
}
|
||||
context()->Plug(eax);
|
||||
}
|
||||
|
||||
|
||||
4
deps/v8/src/ia32/lithium-ia32.cc
vendored
@@ -1986,6 +1986,10 @@ LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
|
||||
|
||||
LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
|
||||
int spill_index = chunk()->GetNextSpillIndex(false); // Not double-width.
|
||||
if (spill_index > LUnallocated::kMaxFixedIndex) {
|
||||
Abort("Too many spill slots needed for OSR");
|
||||
spill_index = 0;
|
||||
}
|
||||
return DefineAsSpilled(new LUnknownOSRValue, spill_index);
|
||||
}
|
||||
|
||||
|
||||
3
deps/v8/src/lithium.h
vendored
@@ -143,7 +143,8 @@ class LUnallocated: public LOperand {
|
||||
};
|
||||
|
||||
static const int kMaxVirtualRegisters = 1 << (kVirtualRegisterWidth + 1);
|
||||
static const int kMaxFixedIndices = 128;
|
||||
static const int kMaxFixedIndex = 63;
|
||||
static const int kMinFixedIndex = -64;
|
||||
|
||||
bool HasIgnorePolicy() const { return policy() == IGNORE; }
|
||||
bool HasNoPolicy() const { return policy() == NONE; }
|
||||
|
||||
1
deps/v8/src/messages.js
vendored
@@ -211,6 +211,7 @@ function FormatMessage(message) {
|
||||
invalid_preparser_data: ["Invalid preparser data for function ", "%0"],
|
||||
strict_mode_with: ["Strict mode code may not include a with statement"],
|
||||
strict_catch_variable: ["Catch variable may not be eval or arguments in strict mode"],
|
||||
too_many_arguments: ["Too many arguments in function call (only 32766 allowed)"],
|
||||
too_many_parameters: ["Too many parameters in function definition"],
|
||||
strict_param_name: ["Parameter name eval or arguments is not allowed in strict mode"],
|
||||
strict_param_dupe: ["Strict mode function may not have duplicate parameter names"],
|
||||
|
||||
6
deps/v8/src/parser.cc
vendored
@@ -3490,6 +3490,12 @@ ZoneList<Expression*>* Parser::ParseArguments(bool* ok) {
|
||||
while (!done) {
|
||||
Expression* argument = ParseAssignmentExpression(true, CHECK_OK);
|
||||
result->Add(argument);
|
||||
if (result->length() > kMaxNumFunctionParameters) {
|
||||
ReportMessageAt(scanner().location(), "too_many_arguments",
|
||||
Vector<const char*>::empty());
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
done = (peek() == Token::RPAREN);
|
||||
if (!done) Expect(Token::COMMA, CHECK_OK);
|
||||
}
|
||||
|
||||
5
deps/v8/src/platform-solaris.cc
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2006-2009 the V8 project authors. All rights reserved.
|
||||
// Copyright 2011 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
@@ -105,7 +105,8 @@ uint64_t OS::CpuFeaturesImpliedByPlatform() {
|
||||
|
||||
|
||||
int OS::ActivationFrameAlignment() {
|
||||
return STACK_ALIGN;
|
||||
// GCC generates code that requires 16 byte alignment such as movdqa.
|
||||
return Max(STACK_ALIGN, 16);
|
||||
}
|
||||
|
||||
|
||||
|
||||
2
deps/v8/src/version.cc
vendored
@@ -35,7 +35,7 @@
|
||||
#define MAJOR_VERSION 3
|
||||
#define MINOR_VERSION 1
|
||||
#define BUILD_NUMBER 8
|
||||
#define PATCH_LEVEL 16
|
||||
#define PATCH_LEVEL 26
|
||||
#define CANDIDATE_VERSION false
|
||||
|
||||
// Define SONAME to have the SCons build the put a specific SONAME into the
|
||||
|
||||
12
deps/v8/src/x64/full-codegen-x64.cc
vendored
@@ -1383,13 +1383,17 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
// Fall through.
|
||||
case ObjectLiteral::Property::COMPUTED:
|
||||
if (key->handle()->IsSymbol()) {
|
||||
VisitForAccumulatorValue(value);
|
||||
__ Move(rcx, key->handle());
|
||||
__ movq(rdx, Operand(rsp, 0));
|
||||
if (property->emit_store()) {
|
||||
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
|
||||
VisitForAccumulatorValue(value);
|
||||
__ Move(rcx, key->handle());
|
||||
__ movq(rdx, Operand(rsp, 0));
|
||||
Handle<Code> ic(Builtins::builtin(
|
||||
is_strict() ? Builtins::StoreIC_Initialize_Strict
|
||||
: Builtins::StoreIC_Initialize));
|
||||
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
||||
PrepareForBailoutForId(key->id(), NO_REGISTERS);
|
||||
} else {
|
||||
VisitForEffect(value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
4
deps/v8/src/x64/lithium-x64.cc
vendored
@@ -1939,6 +1939,10 @@ LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
|
||||
|
||||
LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
|
||||
int spill_index = chunk()->GetNextSpillIndex(false); // Not double-width.
|
||||
if (spill_index > LUnallocated::kMaxFixedIndex) {
|
||||
Abort("Too many spill slots needed for OSR");
|
||||
spill_index = 0;
|
||||
}
|
||||
return DefineAsSpilled(new LUnknownOSRValue, spill_index);
|
||||
}
|
||||
|
||||
|
||||
33
deps/v8/test/mjsunit/regress/regress-1122.js
vendored
@@ -25,12 +25,14 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Test that we can handle functions with up to 32766 arguments, and that
|
||||
// functions with more arguments throw an exception.
|
||||
// Test that we can handle function calls with up to 32766 arguments, and
|
||||
// that function calls with more arguments throw an exception. Apply a
|
||||
// similar limit to the number of function parameters.
|
||||
|
||||
// See http://code.google.com/p/v8/issues/detail?id=1122.
|
||||
// See http://code.google.com/p/v8/issues/detail?id=1122 and
|
||||
// http://code.google.com/p/v8/issues/detail?id=1413.
|
||||
|
||||
function function_with_n_args(n) {
|
||||
function function_with_n_params_and_m_args(n, m) {
|
||||
test_prefix = 'prefix ';
|
||||
test_suffix = ' suffix';
|
||||
var source = 'test_prefix + (function f(';
|
||||
@@ -39,7 +41,7 @@ function function_with_n_args(n) {
|
||||
source += 'arg' + arg;
|
||||
}
|
||||
source += ') { return arg' + (n - n % 2) / 2 + '; })(';
|
||||
for (var arg = 0; arg < n ; arg++) {
|
||||
for (var arg = 0; arg < m ; arg++) {
|
||||
if (arg != 0) source += ',';
|
||||
source += arg;
|
||||
}
|
||||
@@ -47,9 +49,20 @@ function function_with_n_args(n) {
|
||||
return eval(source);
|
||||
}
|
||||
|
||||
assertEquals('prefix 4000 suffix', function_with_n_args(8000));
|
||||
assertEquals('prefix 9000 suffix', function_with_n_args(18000));
|
||||
assertEquals('prefix 16000 suffix', function_with_n_args(32000));
|
||||
assertEquals('prefix 4000 suffix',
|
||||
function_with_n_params_and_m_args(8000, 8000));
|
||||
assertEquals('prefix 3000 suffix',
|
||||
function_with_n_params_and_m_args(6000, 8000));
|
||||
assertEquals('prefix 5000 suffix',
|
||||
function_with_n_params_and_m_args(10000, 8000));
|
||||
assertEquals('prefix 9000 suffix',
|
||||
function_with_n_params_and_m_args(18000, 18000));
|
||||
assertEquals('prefix 16000 suffix',
|
||||
function_with_n_params_and_m_args(32000, 32000));
|
||||
assertEquals('prefix undefined suffix',
|
||||
function_with_n_params_and_m_args(32000, 10000));
|
||||
|
||||
assertThrows("function_with_n_args(35000)");
|
||||
assertThrows("function_with_n_args(100000)");
|
||||
assertThrows("function_with_n_params_and_m_args(35000, 35000)");
|
||||
assertThrows("function_with_n_params_and_m_args(100000, 100000)");
|
||||
assertThrows("function_with_n_params_and_m_args(35000, 30000)");
|
||||
assertThrows("function_with_n_params_and_m_args(30000, 35000)");
|
||||
|
||||
58
deps/v8/test/mjsunit/regress/regress-1257.js
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright 2011 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
function g(y) { assertEquals(y, 12); }
|
||||
|
||||
var X = 0;
|
||||
|
||||
function foo () {
|
||||
var cnt = 0;
|
||||
var l = -1;
|
||||
var x = 0;
|
||||
while (1) switch (l) {
|
||||
case -1:
|
||||
var y = x + 12;
|
||||
l = 0;
|
||||
break;
|
||||
case 0:
|
||||
// Loop for to hit OSR.
|
||||
if (cnt++ < 10000000) {
|
||||
l = 0;
|
||||
break;
|
||||
} else {
|
||||
l = 1;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
// This case will contain deoptimization
|
||||
// because it has no type feedback.
|
||||
g(y);
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
foo();
|
||||
45
deps/v8/test/mjsunit/regress/regress-1401.js
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright 2011 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// See: http://code.google.com/p/v8/issues/detail?id=1401
|
||||
|
||||
var bottom = 0;
|
||||
var sizes = new Array();
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
sizes[i] = 0;
|
||||
}
|
||||
|
||||
function foo() {
|
||||
var size = bottom + 1 + 10;
|
||||
var t = (sizes[++bottom] = size);
|
||||
return t;
|
||||
}
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
assertEquals(i + 11, foo());
|
||||
}
|
||||
36
deps/v8/test/mjsunit/regress/regress-1403.js
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright 2011 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// See: http://code.google.com/p/v8/issues/detail?id=1403
|
||||
|
||||
a = [];
|
||||
Object.prototype.__proto__ = { __proto__: null };
|
||||
a.shift();
|
||||
|
||||
a = [];
|
||||
Array.prototype.__proto__ = { __proto__: null };
|
||||
a.shift();
|
||||
56
deps/v8/test/mjsunit/regress/splice-missing-wb.js
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright 2011 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Flags: --expose-gc
|
||||
|
||||
// Create array large enough to span several page regions.
|
||||
var a = new Array(500);
|
||||
|
||||
// Fill it with values.
|
||||
for (var i = 0; i < a.length; i++) a[i] = {idx:i};
|
||||
|
||||
// Force it into oldspace.
|
||||
gc();
|
||||
gc();
|
||||
|
||||
// Array should be in old space now. Store young object into array.
|
||||
// Region will be marked.
|
||||
a[0] = {idx:0};
|
||||
|
||||
// Delete elements a[2] .. a[201]. Internally we will use
|
||||
// trimming of backing store. a[0] a[1] will be moved to
|
||||
// memory location previously occupied by a[200] a[201].
|
||||
a.splice(2, 200);
|
||||
|
||||
// Force gc and heap verification.
|
||||
gc();
|
||||
|
||||
// Try accessing a[0].idx. It will segfault if write-barrier was accidentally
|
||||
// omitted.
|
||||
assertEquals(0, a[0].idx);
|
||||
assertEquals(1, a[1].idx);
|
||||
assertEquals(202, a[2].idx);
|
||||
@@ -5,7 +5,7 @@ access it with `require('assert')`.
|
||||
|
||||
### assert.fail(actual, expected, message, operator)
|
||||
|
||||
Tests if `actual` is equal to `expected` using the operator provided.
|
||||
Throws an exception that displays the values for `actual` and `expected` separated by the provided operator.
|
||||
|
||||
### assert.ok(value, [message])
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@ method. Here are the different string encodings;
|
||||
|
||||
* `'ascii'` - for 7 bit ASCII data only. This encoding method is very fast, and will
|
||||
strip the high bit if set.
|
||||
Note that this encoding converts a null character (`'\0'` or `'\u0000'`) into
|
||||
`0x20` (character code of a space). If you want to convert a null character
|
||||
into `0x00`, you should use `'utf8'`.
|
||||
|
||||
* `'utf8'` - Multi byte encoded Unicode characters. Many web pages and other document formats use UTF-8.
|
||||
|
||||
@@ -123,7 +126,7 @@ buffer object. It does not change when the contents of the buffer are changed.
|
||||
|
||||
### buffer.copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
|
||||
|
||||
Does a memcpy() between buffers.
|
||||
Does copy between buffers. The source and target regions can be overlapped.
|
||||
|
||||
Example: build two Buffers, then copy `buf1` from byte 16 through byte 19
|
||||
into `buf2`, starting at the 8th byte in `buf2`.
|
||||
|
||||
@@ -65,7 +65,7 @@ The third argument is used to specify additional options, which defaults to:
|
||||
|
||||
`cwd` allows you to specify the working directory from which the process is spawned.
|
||||
Use `env` to specify environment variables that will be visible to the new process.
|
||||
With `customFds` it is possible to hook up the new process' [stdin, stout, stderr] to
|
||||
With `customFds` it is possible to hook up the new process' [stdin, stdout, stderr] to
|
||||
existing streams; `-1` means that a new stream should be created. `setsid`,
|
||||
if set true, will cause the subprocess to be run in a new session.
|
||||
|
||||
@@ -137,6 +137,10 @@ Example of checking for failed exec:
|
||||
}
|
||||
});
|
||||
|
||||
Note that if spawn receives an empty options object, it will result in
|
||||
spawning the process with an empty environment rather than using
|
||||
`process.env`. This due to backwards compatibility issues with a deprecated
|
||||
API.
|
||||
|
||||
See also: `child_process.exec()`
|
||||
|
||||
|
||||
@@ -57,6 +57,8 @@ This can be called many times with new data as it is streamed.
|
||||
Calculates the digest of all of the passed data to be hashed.
|
||||
The `encoding` can be `'hex'`, `'binary'` or `'base64'`.
|
||||
|
||||
Note: `hash` object can not be used after `digest()` method been called.
|
||||
|
||||
|
||||
### crypto.createHmac(algorithm, key)
|
||||
|
||||
@@ -75,13 +77,26 @@ This can be called many times with new data as it is streamed.
|
||||
Calculates the digest of all of the passed data to the hmac.
|
||||
The `encoding` can be `'hex'`, `'binary'` or `'base64'`.
|
||||
|
||||
Note: `hmac` object can not be used after `digest()` method been called.
|
||||
|
||||
### crypto.createCipher(algorithm, key)
|
||||
|
||||
Creates and returns a cipher object, with the given algorithm and key.
|
||||
### crypto.createCipher(algorithm, password)
|
||||
|
||||
Creates and returns a cipher object, with the given algorithm and password.
|
||||
|
||||
`algorithm` is dependent on OpenSSL, examples are `'aes192'`, etc.
|
||||
On recent releases, `openssl list-cipher-algorithms` will display the available cipher algorithms.
|
||||
On recent releases, `openssl list-cipher-algorithms` will display the
|
||||
available cipher algorithms.
|
||||
`password` is used to derive key and IV, which must be `'binary'` encoded
|
||||
string (See the [Buffers](buffers.html) for more information).
|
||||
|
||||
### crypto.createCipheriv(algorithm, key, iv)
|
||||
|
||||
Creates and returns a cipher object, with the given algorithm, key and iv.
|
||||
|
||||
`algorithm` is the same as the `createCipher()`. `key` is a raw key used in
|
||||
algorithm. `iv` is an Initialization vector. `key` and `iv` must be `'binary'`
|
||||
encoded string (See the [Buffers](buffers.html) for more information).
|
||||
|
||||
### cipher.update(data, input_encoding='binary', output_encoding='binary')
|
||||
|
||||
@@ -93,12 +108,20 @@ Returns the enciphered contents, and can be called many times with new data as i
|
||||
|
||||
### cipher.final(output_encoding='binary')
|
||||
|
||||
Returns any remaining enciphered contents, with `output_encoding` being one of: `'binary'`, `'ascii'` or `'utf8'`.
|
||||
Returns any remaining enciphered contents, with `output_encoding` being one of: `'binary'`, `'base64'` or `'hex'`.
|
||||
|
||||
### crypto.createDecipher(algorithm, key)
|
||||
Note: `cipher` object can not be used after `final()` method been called.
|
||||
|
||||
|
||||
### crypto.createDecipher(algorithm, password)
|
||||
|
||||
Creates and returns a decipher object, with the given algorithm and key.
|
||||
This is the mirror of the cipher object above.
|
||||
This is the mirror of the [createCipher()](#crypto.createCipher) above.
|
||||
|
||||
### crypto.createDecipheriv(algorithm, key, iv)
|
||||
|
||||
Creates and returns a decipher object, with the given algorithm, key and iv.
|
||||
This is the mirror of the [createCipheriv()](#crypto.createCipheriv) above.
|
||||
|
||||
### decipher.update(data, input_encoding='binary', output_encoding='binary')
|
||||
|
||||
@@ -108,7 +131,9 @@ The `output_decoding` specifies in what format to return the deciphered plaintex
|
||||
### decipher.final(output_encoding='binary')
|
||||
|
||||
Returns any remaining plaintext which is deciphered,
|
||||
with `output_encoding' being one of: `'binary'`, `'ascii'` or `'utf8'`.
|
||||
with `output_encoding` being one of: `'binary'`, `'ascii'` or `'utf8'`.
|
||||
|
||||
Note: `decipher` object can not be used after `final()` method been called.
|
||||
|
||||
|
||||
### crypto.createSign(algorithm)
|
||||
@@ -129,6 +154,9 @@ Calculates the signature on all the updated data passed through the signer.
|
||||
|
||||
Returns the signature in `output_format` which can be `'binary'`, `'hex'` or `'base64'`.
|
||||
|
||||
Note: `signer` object can not be used after `sign()` method been called.
|
||||
|
||||
|
||||
### crypto.createVerify(algorithm)
|
||||
|
||||
Creates and returns a verification object, with the given algorithm.
|
||||
@@ -139,10 +167,15 @@ This is the mirror of the signing object above.
|
||||
Updates the verifier object with data.
|
||||
This can be called many times with new data as it is streamed.
|
||||
|
||||
### verifier.verify(cert, signature, signature_format='binary')
|
||||
### verifier.verify(object, signature, signature_format='binary')
|
||||
|
||||
Verifies the signed data by using the `cert` which is a string containing
|
||||
the PEM encoded certificate, and `signature`, which is the previously calculates
|
||||
signature for the data, in the `signature_format` which can be `'binary'`, `'hex'` or `'base64'`.
|
||||
Verifies the signed data by using the `object` and `signature`. `object` is a
|
||||
string containing a PEM encoded object, which can be one of RSA public key,
|
||||
DSA public key, or X.509 certificate. `signature` is the previously calculated
|
||||
signature for the data, in the `signature_format` which can be `'binary'`,
|
||||
`'hex'` or `'base64'`.
|
||||
|
||||
Returns true or false depending on the validity of the signature for the data and public key.
|
||||
|
||||
Note: `verifier` object can not be used after `verify()` method been called.
|
||||
|
||||
|
||||
@@ -186,7 +186,7 @@ packets will also be received on the local interface.
|
||||
|
||||
Tells the kernel to join a multicast group with `IP_ADD_MEMBERSHIP` socket option.
|
||||
|
||||
If `multicastAddress` is not specified, the OS will try to add membership to all valid
|
||||
If `multicastInterface` is not specified, the OS will try to add membership to all valid
|
||||
interfaces.
|
||||
|
||||
### dgram.dropMembership(multicastAddress, [multicastInterface])
|
||||
@@ -196,5 +196,5 @@ Opposite of `addMembership` - tells the kernel to leave a multicast group with
|
||||
when the socket is closed or process terminates, so most apps will never need to call
|
||||
this.
|
||||
|
||||
If `multicastAddress` is not specified, the OS will try to drop membership to all valid
|
||||
If `multicastInterface` is not specified, the OS will try to drop membership to all valid
|
||||
interfaces.
|
||||
|
||||
@@ -52,6 +52,9 @@ In busy processes, the programmer is _strongly encouraged_ to use the
|
||||
asynchronous versions of these calls. The synchronous versions will block
|
||||
the entire process until they complete--halting all connections.
|
||||
|
||||
Relative path to filename can be used, remember however that this path will be relative
|
||||
to `process.cwd()`.
|
||||
|
||||
### fs.rename(path1, path2, [callback])
|
||||
|
||||
Asynchronous rename(2). No arguments other than a possible exception are given
|
||||
@@ -70,6 +73,33 @@ given to the completion callback.
|
||||
|
||||
Synchronous ftruncate(2).
|
||||
|
||||
### fs.chown(path, uid, gid, [callback])
|
||||
|
||||
Asycnronous chown(2). No arguments other than a possible exception are given
|
||||
to the completion callback.
|
||||
|
||||
### fs.chownSync(path, uid, gid)
|
||||
|
||||
Synchronous chown(2).
|
||||
|
||||
### fs.fchown(path, uid, gid, [callback])
|
||||
|
||||
Asycnronous fchown(2). No arguments other than a possible exception are given
|
||||
to the completion callback.
|
||||
|
||||
### fs.fchownSync(path, uid, gid)
|
||||
|
||||
Synchronous fchown(2).
|
||||
|
||||
### fs.lchown(path, uid, gid, [callback])
|
||||
|
||||
Asycnronous lchown(2). No arguments other than a possible exception are given
|
||||
to the completion callback.
|
||||
|
||||
### fs.lchownSync(path, uid, gid)
|
||||
|
||||
Synchronous lchown(2).
|
||||
|
||||
### fs.chmod(path, mode, [callback])
|
||||
|
||||
Asynchronous chmod(2). No arguments other than a possible exception are given
|
||||
@@ -79,6 +109,24 @@ to the completion callback.
|
||||
|
||||
Synchronous chmod(2).
|
||||
|
||||
### fs.fchmod(fd, mode, [callback])
|
||||
|
||||
Asynchronous fchmod(2). No arguments other than a possible exception
|
||||
are given to the completion callback.
|
||||
|
||||
### fs.fchmodSync(path, mode)
|
||||
|
||||
Synchronous fchmod(2).
|
||||
|
||||
### fs.lchmod(fd, mode, [callback])
|
||||
|
||||
Asynchronous lchmod(2). No arguments other than a possible exception
|
||||
are given to the completion callback.
|
||||
|
||||
### fs.lchmodSync(path, mode)
|
||||
|
||||
Synchronous lchmod(2).
|
||||
|
||||
### fs.stat(path, [callback])
|
||||
|
||||
Asynchronous stat(2). The callback gets two arguments `(err, stats)` where
|
||||
@@ -103,14 +151,15 @@ See the [fs.Stats](#fs.Stats) section below for more information.
|
||||
### fs.lstat(path, [callback])
|
||||
|
||||
Asynchronous lstat(2). The callback gets two arguments `(err, stats)` where
|
||||
`stats` is a `fs.Stats` object. lstat() is identical to stat(), except that if
|
||||
path is a symbolic link, then the link itself is stat-ed, not the file that it
|
||||
`stats` is a `fs.Stats` object. `lstat()` is identical to `stat()`, except that if
|
||||
`path` is a symbolic link, then the link itself is stat-ed, not the file that it
|
||||
refers to.
|
||||
|
||||
### fs.fstat(fd, [callback])
|
||||
|
||||
Asynchronous fstat(2). The callback gets two arguments `(err, stats)` where
|
||||
`stats` is a `fs.Stats` object.
|
||||
`stats` is a `fs.Stats` object. `fstat()` is identical to `stat()`, except that
|
||||
the file to be stat-ed is specified by the file descriptor `fd`.
|
||||
|
||||
### fs.statSync(path)
|
||||
|
||||
@@ -209,8 +258,27 @@ Synchronous close(2).
|
||||
|
||||
### fs.open(path, flags, [mode], [callback])
|
||||
|
||||
Asynchronous file open. See open(2). Flags can be 'r', 'r+', 'w', 'w+', 'a',
|
||||
or 'a+'. `mode` defaults to 0666. The callback gets two arguments `(err, fd)`.
|
||||
Asynchronous file open. See open(2). `flags` can be:
|
||||
|
||||
* `'r'` - Open file for reading.
|
||||
An exception occurs if the file does not exist.
|
||||
|
||||
* `'r+'` - Open file for reading and writing.
|
||||
An exception occurs if the file does not exist.
|
||||
|
||||
* `'w'` - Open file for writing.
|
||||
The file is created (if it does not exist) or truncated (if it exists).
|
||||
|
||||
* `'w+'` - Open file for reading and writing.
|
||||
The file is created (if it does not exist) or truncated (if it exists).
|
||||
|
||||
* `'a'` - Open file for appending.
|
||||
The file is created if it does not exist.
|
||||
|
||||
* `'a+'` - Open file for reading and appending.
|
||||
The file is created if it does not exist.
|
||||
|
||||
`mode` defaults to `0666`. The callback gets two arguments `(err, fd)`.
|
||||
|
||||
### fs.openSync(path, flags, [mode])
|
||||
|
||||
@@ -228,7 +296,7 @@ current position.
|
||||
See pwrite(2).
|
||||
|
||||
The callback will be given three arguments `(err, written, buffer)` where `written`
|
||||
specifies how many _bytes_ were written into `buffer`.
|
||||
specifies how many _bytes_ were written from `buffer`.
|
||||
|
||||
Note that it is unsafe to use `fs.write` multiple times on the same file
|
||||
without waiting for the callback. For this scenario,
|
||||
@@ -320,7 +388,7 @@ value in milliseconds. The default is `{ persistent: true, interval: 0 }`.
|
||||
The `listener` gets two arguments the current stat object and the previous
|
||||
stat object:
|
||||
|
||||
fs.watchFile(f, function (curr, prev) {
|
||||
fs.watchFile('message.text', function (curr, prev) {
|
||||
console.log('the current mtime is: ' + curr.mtime);
|
||||
console.log('the previous mtime was: ' + prev.mtime);
|
||||
});
|
||||
@@ -328,7 +396,7 @@ stat object:
|
||||
These stat objects are instances of `fs.Stat`.
|
||||
|
||||
If you want to be notified when the file was modified, not just accessed
|
||||
you need to compare `curr.mtime` and `prev.mtime.
|
||||
you need to compare `curr.mtime` and `prev.mtime`.
|
||||
|
||||
|
||||
### fs.unwatchFile(filename)
|
||||
@@ -350,7 +418,13 @@ Objects returned from `fs.stat()` and `fs.lstat()` are of this type.
|
||||
|
||||
## fs.ReadStream
|
||||
|
||||
`ReadStream` is a `Readable Stream`.
|
||||
`ReadStream` is a [Readable Stream](streams.html#readable_Stream).
|
||||
|
||||
### Event: 'open'
|
||||
|
||||
`function (fd) { }`
|
||||
|
||||
`fd` is the file descriptor used by the ReadStream.
|
||||
|
||||
### fs.createReadStream(path, [options])
|
||||
|
||||
@@ -376,7 +450,7 @@ An example to read the last 10 bytes of a file which is 100 bytes long:
|
||||
|
||||
## fs.WriteStream
|
||||
|
||||
`WriteStream` is a `Writable Stream`.
|
||||
`WriteStream` is a [Writable Stream](streams.html#writable_Stream).
|
||||
|
||||
### Event: 'open'
|
||||
|
||||
|
||||
@@ -32,6 +32,12 @@ To require modules. See the [Modules](modules.html#modules) section.
|
||||
Use the internal `require()` machinery to look up the location of a module,
|
||||
but rather than loading the module, just return the resolved filename.
|
||||
|
||||
### require.cache
|
||||
|
||||
Modules are cached in this object when they are required. By deleting a key
|
||||
value from this object, the next `require` will reload the module.
|
||||
|
||||
|
||||
### require.paths
|
||||
|
||||
An array of search paths for `require()`. This array can be modified to add
|
||||
@@ -73,6 +79,15 @@ A reference to the current module. In particular
|
||||
for more information.
|
||||
`module` isn't actually a global but rather local to each module.
|
||||
|
||||
|
||||
### exports
|
||||
|
||||
An object which is shared between all instances of the current module and
|
||||
made accessible through `require()`.
|
||||
`exports` is the same as the `module.exports` object. See `src/node.js`
|
||||
for more information.
|
||||
`exports` isn't actually a global but rather local to each module.
|
||||
|
||||
### setTimeout(cb, ms)
|
||||
### clearTimeout(t)
|
||||
### setInterval(cb, ms)
|
||||
|
||||
@@ -38,11 +38,11 @@ per connection (in the case of keep-alive connections).
|
||||
|
||||
### Event: 'connection'
|
||||
|
||||
`function (stream) { }`
|
||||
`function (socket) { }`
|
||||
|
||||
When a new TCP stream is established. `stream` is an object of type
|
||||
`net.Stream`. Usually users will not want to access this event. The
|
||||
`stream` can also be accessed at `request.connection`.
|
||||
When a new TCP stream is established. `socket` is an object of type
|
||||
`net.Socket`. Usually users will not want to access this event. The
|
||||
`socket` can also be accessed at `request.connection`.
|
||||
|
||||
### Event: 'close'
|
||||
|
||||
@@ -52,7 +52,7 @@ per connection (in the case of keep-alive connections).
|
||||
|
||||
### Event: 'checkContinue'
|
||||
|
||||
`function (request, response) {}`
|
||||
`function (request, response) { }`
|
||||
|
||||
Emitted each time a request with an http Expect: 100-continue is received.
|
||||
If this event isn't listened for, the server will automatically respond
|
||||
@@ -68,7 +68,7 @@ not be emitted.
|
||||
|
||||
### Event: 'upgrade'
|
||||
|
||||
`function (request, socket, head)`
|
||||
`function (request, socket, head) { }`
|
||||
|
||||
Emitted each time a client requests a http upgrade. If this event isn't
|
||||
listened for, then clients requesting an upgrade will have their connections
|
||||
@@ -84,7 +84,7 @@ sent to the server on that socket.
|
||||
|
||||
### Event: 'clientError'
|
||||
|
||||
`function (exception) {}`
|
||||
`function (exception) { }`
|
||||
|
||||
If a client connection emits an 'error' event - it will forwarded here.
|
||||
|
||||
@@ -239,7 +239,7 @@ Resumes a paused request.
|
||||
|
||||
### request.connection
|
||||
|
||||
The `net.Stream` object associated with the connection.
|
||||
The `net.Socket` object associated with the connection.
|
||||
|
||||
|
||||
With HTTPS support, use request.connection.verifyPeer() and
|
||||
@@ -283,6 +283,8 @@ Note: that Content-Length is given in bytes not characters. The above example
|
||||
works because the string `'hello world'` contains only single byte characters.
|
||||
If the body contains higher coded characters then `Buffer.byteLength()`
|
||||
should be used to determine the number of bytes in a given encoding.
|
||||
And Node does not check whether Content-Length and the length of the body
|
||||
which has been transmitted are equal or not.
|
||||
|
||||
### response.statusCode
|
||||
|
||||
@@ -294,6 +296,9 @@ Example:
|
||||
|
||||
response.statusCode = 404;
|
||||
|
||||
After response header was sent to the client, this property indicates the
|
||||
status code which was sent out.
|
||||
|
||||
### response.setHeader(name, value)
|
||||
|
||||
Sets a single header value for implicit headers. If this header already exists
|
||||
@@ -393,6 +398,10 @@ Options:
|
||||
- `path`: Request path. Should include query string and fragments if any.
|
||||
E.G. `'/index.html?page=12'`
|
||||
- `headers`: An object containing request headers.
|
||||
- `agent`: Controls `Agent` behavior. Possible values:
|
||||
- `undefined` (default): use default `Agent` for this host and port.
|
||||
- `Agent` object: explicitly use the passed in `Agent`.
|
||||
- `false`: explicitly generate a new `Agent` for this host and port. `Agent` will not be re-used.
|
||||
|
||||
`http.request()` returns an instance of the `http.ClientRequest`
|
||||
class. The `ClientRequest` instance is a writable stream. If one needs to
|
||||
@@ -476,7 +485,7 @@ agent. The `http.getAgent()` function allows you to access the agents.
|
||||
|
||||
### Event: 'upgrade'
|
||||
|
||||
`function (response, socket, head)`
|
||||
`function (response, socket, head) { }`
|
||||
|
||||
Emitted each time a server responds to a request with an upgrade. If this
|
||||
event isn't being listened for, clients receiving an upgrade header will have
|
||||
@@ -530,14 +539,6 @@ A client server pair that show you how to listen for the `upgrade` event using `
|
||||
});
|
||||
|
||||
|
||||
### Event: 'continue'
|
||||
|
||||
`function ()`
|
||||
|
||||
Emitted when the server sends a '100 Continue' HTTP response, usually because
|
||||
the request contained 'Expect: 100-continue'. This is an instruction that
|
||||
the client should send the request body.
|
||||
|
||||
### agent.maxSockets
|
||||
|
||||
By default set to 5. Determines how many concurrent sockets the agent can have open.
|
||||
@@ -590,9 +591,19 @@ event, the entire body will be caught.
|
||||
});
|
||||
|
||||
This is a `Writable Stream`.
|
||||
Note: Node does not check whether Content-Length and the length of the body
|
||||
which has been transmitted are equal or not.
|
||||
|
||||
This is an `EventEmitter` with the following events:
|
||||
|
||||
### Event: 'continue'
|
||||
|
||||
`function () { }`
|
||||
|
||||
Emitted when the server sends a '100 Continue' HTTP response, usually because
|
||||
the request contained 'Expect: 100-continue'. This is an instruction that
|
||||
the client should send the request body.
|
||||
|
||||
### Event 'response'
|
||||
|
||||
`function (response) { }`
|
||||
@@ -639,18 +650,27 @@ The response implements the `Readable Stream` interface.
|
||||
|
||||
### Event: 'data'
|
||||
|
||||
`function (chunk) {}`
|
||||
`function (chunk) { }`
|
||||
|
||||
Emitted when a piece of the message body is received.
|
||||
|
||||
|
||||
### Event: 'end'
|
||||
|
||||
`function () {}`
|
||||
`function () { }`
|
||||
|
||||
Emitted exactly once for each message. No arguments. After
|
||||
emitted no other events will be emitted on the response.
|
||||
|
||||
### Event: 'close'
|
||||
|
||||
`function (err) { }`
|
||||
|
||||
Indicates that the underlaying connection was terminated before
|
||||
`end` event was emitted.
|
||||
See [http.ServerRequest](#http.ServerRequest)'s `'close'` event for more
|
||||
information.
|
||||
|
||||
### response.statusCode
|
||||
|
||||
The 3-digit HTTP response status code. E.G. `404`.
|
||||
|
||||
@@ -68,8 +68,7 @@ parent directory of the current module, and adds `/node_modules`, and
|
||||
attempts to load the module from that location.
|
||||
|
||||
If it is not found there, then it moves to the parent directory, and so
|
||||
on, until either the module is found, or the root of the tree is
|
||||
reached.
|
||||
on, until the root of the tree is reached.
|
||||
|
||||
For example, if the file at `'/home/ry/projects/foo.js'` called
|
||||
`require('bar.js')`, then node would look in the following locations, in
|
||||
@@ -83,28 +82,6 @@ this order:
|
||||
This allows programs to localize their dependencies, so that they do not
|
||||
clash.
|
||||
|
||||
#### Optimizations to the `node_modules` Lookup Process
|
||||
|
||||
When there are many levels of nested dependencies, it is possible for
|
||||
these file trees to get fairly long. The following optimizations are thus
|
||||
made to the process.
|
||||
|
||||
First, `/node_modules` is never appended to a folder already ending in
|
||||
`/node_modules`.
|
||||
|
||||
Second, if the file calling `require()` is already inside a `node_modules`
|
||||
hierarchy, then the top-most `node_modules` folder is treated as the
|
||||
root of the search tree.
|
||||
|
||||
For example, if the file at
|
||||
`'/home/ry/projects/foo/node_modules/bar/node_modules/baz/quux.js'`
|
||||
called `require('asdf.js')`, then node would search the following
|
||||
locations:
|
||||
|
||||
* `/home/ry/projects/foo/node_modules/bar/node_modules/baz/node_modules/asdf.js`
|
||||
* `/home/ry/projects/foo/node_modules/bar/node_modules/asdf.js`
|
||||
* `/home/ry/projects/foo/node_modules/asdf.js`
|
||||
|
||||
### Folders as Modules
|
||||
|
||||
It is convenient to organize programs and libraries into self-contained
|
||||
@@ -223,7 +200,8 @@ in pseudocode of what require.resolve does:
|
||||
a. Parse X/package.json, and look for "main" field.
|
||||
b. let M = X + (json main field)
|
||||
c. LOAD_AS_FILE(M)
|
||||
2. LOAD_AS_FILE(X/index)
|
||||
2. If X/index.js is a file, load X/index.js as JavaScript text. STOP
|
||||
3. If X/index.node is a file, load X/index.node as binary addon. STOP
|
||||
|
||||
LOAD_NODE_MODULES(X, START)
|
||||
1. let DIRS=NODE_MODULES_PATHS(START)
|
||||
@@ -271,9 +249,10 @@ Loading from the `require.paths` locations is only performed if the
|
||||
module could not be found using the `node_modules` algorithm above.
|
||||
Global modules are lower priority than bundled dependencies.
|
||||
|
||||
#### **Note:** Please Avoid Modifying `require.paths`
|
||||
#### **Note:** Please Avoid Using `require.paths`
|
||||
|
||||
`require.paths` may disappear in a future release.
|
||||
`require.paths` will only be supported through the end of the v0.4
|
||||
stable branch. It is removed from node as of v0.5.
|
||||
|
||||
While it seemed like a good idea at the time, and enabled a lot of
|
||||
useful experimentation, in practice a mutable `require.paths` list is
|
||||
|
||||
@@ -280,7 +280,8 @@ What platform you're running on. `'linux2'`, `'darwin'`, etc.
|
||||
|
||||
### process.memoryUsage()
|
||||
|
||||
Returns an object describing the memory usage of the Node process.
|
||||
Returns an object describing the memory usage of the Node process
|
||||
measured in bytes.
|
||||
|
||||
var util = require('util');
|
||||
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
## Readline
|
||||
|
||||
To use this module, do `require('readline')`. Readline allows reading of a
|
||||
stream (such as STDIN) on a line-by-line basis.
|
||||
|
||||
Note that once you've invoked this module, your node program will not
|
||||
terminate until you've closed the interface, and the STDIN stream. Here's how
|
||||
to allow your program to gracefully terminate:
|
||||
|
||||
var rl = require('readline');
|
||||
|
||||
var i = rl.createInterface(process.sdtin, process.stdout, null);
|
||||
i.question("What do you think of node.js?", function(answer) {
|
||||
// TODO: Log the answer in a database
|
||||
console.log("Thank you for your valuable feedback.");
|
||||
|
||||
// These two lines together allow the program to terminate. Without
|
||||
// them, it would run forever.
|
||||
i.close();
|
||||
process.stdin.destroy();
|
||||
});
|
||||
|
||||
### rl.createInterface(input, output, completer)
|
||||
|
||||
Takes two streams and creates a readline interface. The `completer` function
|
||||
is used for autocompletion. When given a substring, it returns `[[substr1,
|
||||
substr2, ...], originalsubstring]`.
|
||||
|
||||
`createInterface` is commonly used with `process.stdin` and
|
||||
`process.stdout` in order to accept user input:
|
||||
|
||||
var readline = require('readline'),
|
||||
rl = readline.createInterface(process.stdin, process.stdout);
|
||||
|
||||
### rl.setPrompt(prompt, length)
|
||||
|
||||
Sets the prompt, for example when you run `node` on the command line, you see
|
||||
`> `, which is node's prompt.
|
||||
|
||||
### rl.prompt()
|
||||
|
||||
Readies readline for input from the user, putting the current `setPrompt`
|
||||
options on a new line, giving the user a new spot to write.
|
||||
|
||||
<!-- ### rl.getColumns() Not available? -->
|
||||
|
||||
### rl.question(query, callback)
|
||||
|
||||
Prepends the prompt with `query` and invokes `callback` with the user's
|
||||
response. Displays the query to the user, and then invokes `callback` with the
|
||||
user's response after it has been typed.
|
||||
|
||||
Example usage:
|
||||
|
||||
interface.question('What is your favorite food?', function(answer) {
|
||||
console.log('Oh, so your favorite food is ' + answer);
|
||||
});
|
||||
|
||||
### rl.close()
|
||||
|
||||
Closes tty.
|
||||
|
||||
### rl.pause()
|
||||
|
||||
Pauses tty.
|
||||
|
||||
### rl.resume()
|
||||
|
||||
Resumes tty.
|
||||
|
||||
### rl.write()
|
||||
|
||||
Writes to tty.
|
||||
|
||||
### Event: 'line'
|
||||
|
||||
`function (line) {}`
|
||||
|
||||
Emitted whenever the `in` stream receives a `\n`, usually received when the
|
||||
user hits enter, or return. This is a good hook to listen for user input.
|
||||
|
||||
Example of listening for `line`:
|
||||
|
||||
rl.on('line', function (cmd) {
|
||||
console.log('You just typed: '+cmd);
|
||||
});
|
||||
|
||||
### Event: 'close'
|
||||
|
||||
`function () {}`
|
||||
|
||||
Emitted whenever the `in` stream receives a `^C` or `^D`, respectively known
|
||||
as `SIGINT` and `EOT`. This is a good way to know the user is finished using
|
||||
your program.
|
||||
|
||||
Example of listening for `close`, and exiting the program afterward:
|
||||
|
||||
rl.on('close', function() {
|
||||
console.log('goodbye!');
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
Here's an example of how to use all these together to craft a tiny command
|
||||
line interface:
|
||||
|
||||
var readline = require('readline'),
|
||||
rl = readline.createInterface(process.stdin, process.stdout),
|
||||
prefix = 'OHAI> ';
|
||||
|
||||
rl.on('line', function(line) {
|
||||
switch(line.trim()) {
|
||||
case 'hello':
|
||||
console.log('world!');
|
||||
break;
|
||||
default:
|
||||
console.log('Say what? I might have heard `' + line.trim() + '`');
|
||||
break;
|
||||
}
|
||||
rl.setPrompt(prefix, prefix.length);
|
||||
rl.prompt();
|
||||
}).on('close', function() {
|
||||
console.log('Have a great day!');
|
||||
process.exit(0);
|
||||
});
|
||||
console.log(prefix + 'Good to see you. Try typing stuff.');
|
||||
rl.setPrompt(prefix, prefix.length);
|
||||
rl.prompt();
|
||||
|
||||
|
||||
Take a look at this slightly more complicated
|
||||
[example](https://gist.github.com/901104), and
|
||||
[http-console](http://github.com/cloudhead/http-console) for a real-life use
|
||||
case.
|
||||
@@ -1,133 +0,0 @@
|
||||
## Readline
|
||||
|
||||
To use this module, do `require('readline')`. Readline allows reading of a
|
||||
stream (such as STDIN) on a line-by-line basis.
|
||||
|
||||
Note that once you've invoked this module, your node program will not
|
||||
terminate until you've closed the interface, and the STDIN stream. Here's how
|
||||
to allow your program to gracefully terminate:
|
||||
|
||||
var rl = require('readline');
|
||||
|
||||
var i = rl.createInterface(process.sdtin, process.stdout, null);
|
||||
i.question("What do you think of node.js?", function(answer) {
|
||||
// TODO: Log the answer in a database
|
||||
console.log("Thank you for your valuable feedback.");
|
||||
|
||||
// These two lines together allow the program to terminate. Without
|
||||
// them, it would run forever.
|
||||
i.close();
|
||||
process.stdin.destroy();
|
||||
});
|
||||
|
||||
### rl.createInterface(input, output, completer)
|
||||
|
||||
Takes two streams and creates a readline interface. The `completer` function
|
||||
is used for autocompletion. When given a substring, it returns `[[substr1,
|
||||
substr2, ...], originalsubstring]`.
|
||||
|
||||
`createInterface` is commonly used with `process.stdin` and
|
||||
`process.stdout` in order to accept user input:
|
||||
|
||||
var readline = require('readline'),
|
||||
rl = readline.createInterface(process.stdin, process.stdout);
|
||||
|
||||
### rl.setPrompt(prompt, length)
|
||||
|
||||
Sets the prompt, for example when you run `node` on the command line, you see
|
||||
`> `, which is node's prompt.
|
||||
|
||||
### rl.prompt()
|
||||
|
||||
Readies readline for input from the user, putting the current `setPrompt`
|
||||
options on a new line, giving the user a new spot to write.
|
||||
|
||||
<!-- ### rl.getColumns() Not available? -->
|
||||
|
||||
### rl.question(query, callback)
|
||||
|
||||
Prepends the prompt with `query` and invokes `callback` with the user's
|
||||
response. Displays the query to the user, and then invokes `callback` with the
|
||||
user's response after it has been typed.
|
||||
|
||||
Example usage:
|
||||
|
||||
interface.question('What is your favorite food?', function(answer) {
|
||||
console.log('Oh, so your favorite food is ' + answer);
|
||||
});
|
||||
|
||||
### rl.close()
|
||||
|
||||
Closes tty.
|
||||
|
||||
### rl.pause()
|
||||
|
||||
Pauses tty.
|
||||
|
||||
### rl.resume()
|
||||
|
||||
Resumes tty.
|
||||
|
||||
### rl.write()
|
||||
|
||||
Writes to tty.
|
||||
|
||||
### Event: 'line'
|
||||
|
||||
`function (line) {}`
|
||||
|
||||
Emitted whenever the `in` stream receives a `\n`, usually received when the
|
||||
user hits enter, or return. This is a good hook to listen for user input.
|
||||
|
||||
Example of listening for `line`:
|
||||
|
||||
rl.on('line', function (cmd) {
|
||||
console.log('You just typed: '+cmd);
|
||||
});
|
||||
|
||||
### Event: 'close'
|
||||
|
||||
`function () {}`
|
||||
|
||||
Emitted whenever the `in` stream receives a `^C` or `^D`, respectively known
|
||||
as `SIGINT` and `EOT`. This is a good way to know the user is finished using
|
||||
your program.
|
||||
|
||||
Example of listening for `close`, and exiting the program afterward:
|
||||
|
||||
rl.on('close', function() {
|
||||
console.log('goodbye!');
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
Here's an example of how to use all these together to craft a tiny command
|
||||
line interface:
|
||||
|
||||
var readline = require('readline'),
|
||||
rl = readline.createInterface(process.stdin, process.stdout),
|
||||
prefix = 'OHAI> ';
|
||||
|
||||
rl.on('line', function(line) {
|
||||
switch(line.trim()) {
|
||||
case 'hello':
|
||||
console.log('world!');
|
||||
break;
|
||||
default:
|
||||
console.log('Say what? I might have heard `' + line.trim() + '`');
|
||||
break;
|
||||
}
|
||||
rl.setPrompt(prefix, prefix.length);
|
||||
rl.prompt();
|
||||
}).on('close', function() {
|
||||
console.log('Have a great day!');
|
||||
process.exit(0);
|
||||
});
|
||||
console.log(prefix + 'Good to see you. Try typing stuff.');
|
||||
rl.setPrompt(prefix, prefix.length);
|
||||
rl.prompt();
|
||||
|
||||
|
||||
Take a look at this slightly more complicated
|
||||
[example](https://gist.github.com/901104), and
|
||||
[http-console](http://github.com/cloudhead/http-console) for a real-life use
|
||||
case.
|
||||
@@ -9,8 +9,30 @@ Prints to stdout with newline. This function can take multiple arguments in a
|
||||
|
||||
console.log('count: %d', count);
|
||||
|
||||
If formating elements are not found in the first string then `util.inspect`
|
||||
is used on each argument.
|
||||
The first argument is a string that contains zero or more *placeholders*.
|
||||
Each placeholder is replaced with the converted value from its corresponding
|
||||
argument. Supported placeholders are:
|
||||
|
||||
* `%s` - String.
|
||||
* `%d` - Number (both integer and float).
|
||||
* `%j` - JSON.
|
||||
|
||||
If the placeholder does not have a corresponding argument, `undefined` is used.
|
||||
|
||||
console.log('%s:%s', 'foo'); // 'foo:undefined'
|
||||
|
||||
If there are more arguments than placeholders, the extra arguments are
|
||||
converted to strings with `util.inspect()` and these strings are concatenated,
|
||||
delimited by a space.
|
||||
|
||||
console.log('%s:%s', 'foo', 'bar', 'baz'); // 'foo:bar baz'
|
||||
|
||||
If the first argument is not a format string then `console.log()` prints
|
||||
a string that is the concatenation of all its arguments separated by spaces.
|
||||
Each argument is converted to a string with `util.inspect()`.
|
||||
|
||||
console.log(1, 2, 3); // '1 2 3'
|
||||
|
||||
|
||||
### console.info()
|
||||
|
||||
@@ -35,7 +57,7 @@ Mark a time.
|
||||
Finish timer, record output. Example
|
||||
|
||||
console.time('100-elements');
|
||||
while (var i = 0; i < 100; i++) {
|
||||
for (var i = 0; i < 100; i++) {
|
||||
;
|
||||
}
|
||||
console.timeEnd('100-elements');
|
||||
|
||||
@@ -42,13 +42,13 @@ defaults to `localhost`.) `options` should be an object which specifies
|
||||
omitted several well known "root" CAs will be used, like VeriSign.
|
||||
These are used to authorize connections.
|
||||
|
||||
`tls.connect()` returns a cleartext `CryptoStream` object.
|
||||
`tls.connect()` returns a [CleartextStream](#tls.CleartextStream) object.
|
||||
|
||||
After the TLS/SSL handshake the `callback` is called. The `callback` will be
|
||||
called no matter if the server's certificate was authorized or not. It is up
|
||||
to the user to test `s.authorized` to see if the server certificate was
|
||||
signed by one of the specified CAs. If `s.authorized === false` then the error
|
||||
can be found in `s.authorizationError`.
|
||||
to the user to test `s.authorized` to see if the server certificate was signed
|
||||
by one of the specified CAs. If `s.authorized === false` then the error can be
|
||||
found in `s.authorizationError`.
|
||||
|
||||
|
||||
### STARTTLS
|
||||
@@ -56,13 +56,42 @@ can be found in `s.authorizationError`.
|
||||
In the v0.4 branch no function exists for starting a TLS session on an
|
||||
already existing TCP connection. This is possible it just requires a bit of
|
||||
work. The technique is to use `tls.createSecurePair()` which returns two
|
||||
streams: an encrypted stream and a plaintext stream. The encrypted stream is then
|
||||
piped to the socket, the plaintext stream is what the user interacts with thereafter.
|
||||
streams: an encrypted stream and a cleartext stream. The encrypted stream is
|
||||
then piped to the socket, the cleartext stream is what the user interacts with
|
||||
thereafter.
|
||||
|
||||
[Here is some code that does it.](http://gist.github.com/848444)
|
||||
|
||||
### pair = tls.createSecurePair([credentials], [isServer], [requestCert], [rejectUnauthorized])
|
||||
|
||||
Creates a new secure pair object with two streams, one of which reads/writes
|
||||
encrypted data, and one reads/writes cleartext data.
|
||||
Generally the encrypted one is piped to/from an incoming encrypted data stream,
|
||||
and the cleartext one is used as a replacement for the initial encrypted stream.
|
||||
|
||||
- `credentials`: A credentials object from crypto.createCredentials( ... )
|
||||
|
||||
- `isServer`: A boolean indicating whether this tls connection should be
|
||||
opened as a server or a client.
|
||||
|
||||
- `requestCert`: A boolean indicating whether a server should request a
|
||||
certificate from a connecting client. Only applies to server connections.
|
||||
|
||||
- `rejectUnauthorized`: A boolean indicating whether a server should
|
||||
automatically reject clients with invalid certificates. Only applies to
|
||||
servers with `requestCert` enabled.
|
||||
|
||||
`tls.createSecurePair()` returns a SecurePair object with
|
||||
[cleartext](#tls.CleartextStream) and `encrypted` stream properties.
|
||||
|
||||
#### Event: 'secure'
|
||||
|
||||
The event is emitted from the SecurePair once the pair has successfully
|
||||
established a secure connection.
|
||||
|
||||
Similarly to the checking for the server 'secureConnection' event,
|
||||
pair.cleartext.authorized should be checked to confirm whether the certificate
|
||||
used properly authorized.
|
||||
|
||||
### tls.Server
|
||||
|
||||
@@ -121,8 +150,9 @@ has these possibilities:
|
||||
`function (cleartextStream) {}`
|
||||
|
||||
This event is emitted after a new connection has been successfully
|
||||
handshaked. The argument is a duplex instance of `stream.Stream`. It has all
|
||||
the common stream methods and events.
|
||||
handshaked. The argument is a instance of
|
||||
[CleartextStream](#tls.CleartextStream). It has all the common stream methods
|
||||
and events.
|
||||
|
||||
`cleartextStream.authorized` is a boolean value which indicates if the
|
||||
client has verified by one of the supplied certificate authorities for the
|
||||
@@ -153,8 +183,57 @@ event.
|
||||
|
||||
#### server.maxConnections
|
||||
|
||||
Set this property to reject connections when the server's connection count gets high.
|
||||
Set this property to reject connections when the server's connection count
|
||||
gets high.
|
||||
|
||||
#### server.connections
|
||||
|
||||
The number of concurrent connections on the server.
|
||||
|
||||
|
||||
### tls.CleartextStream
|
||||
|
||||
This is a stream on top of the *Encrypted* stream that makes it possible to
|
||||
read/write an encrypted data as a cleartext data.
|
||||
|
||||
This instance implements a duplex [Stream](streams.html#streams) interfaces.
|
||||
It has all the common stream methods and events.
|
||||
|
||||
#### cleartextStream.authorized
|
||||
|
||||
A boolean that is `true` if the peer certificate was signed by one of the
|
||||
specified CAs, otherwise `false`
|
||||
|
||||
#### cleartextStream.authorizationError
|
||||
|
||||
The reason why the peer's certificate has not been verified. This property
|
||||
becomes available only when `cleartextStream.authorized === false`.
|
||||
|
||||
#### cleartextStream.getPeerCertificate()
|
||||
|
||||
Returns an object representing the peer's certicicate. The returned object has
|
||||
some properties corresponding to the field of the certificate.
|
||||
|
||||
Example:
|
||||
|
||||
{ subject:
|
||||
{ C: 'UK',
|
||||
ST: 'Acknack Ltd',
|
||||
L: 'Rhys Jones',
|
||||
O: 'node.js',
|
||||
OU: 'Test TLS Certificate',
|
||||
CN: 'localhost' },
|
||||
issuer:
|
||||
{ C: 'UK',
|
||||
ST: 'Acknack Ltd',
|
||||
L: 'Rhys Jones',
|
||||
O: 'node.js',
|
||||
OU: 'Test TLS Certificate',
|
||||
CN: 'localhost' },
|
||||
valid_from: 'Nov 11 09:52:22 2009 GMT',
|
||||
valid_to: 'Nov 6 09:52:22 2029 GMT',
|
||||
fingerprint: '2A:7A:C2:DD:E5:F9:CC:53:72:35:99:7A:02:5A:71:38:52:EC:8A:DF' }
|
||||
|
||||
If the peer does not provide a certificate, it returns `null` or an empty
|
||||
object.
|
||||
|
||||
|
||||
@@ -42,11 +42,17 @@ string will not be in the parsed object. Examples are shown for the URL
|
||||
|
||||
The following methods are provided by the URL module:
|
||||
|
||||
### url.parse(urlStr, parseQueryString=false)
|
||||
### url.parse(urlStr, parseQueryString=false, slashesDenoteHost=false)
|
||||
|
||||
Take a URL string, and return an object. Pass `true` as the second argument to also parse
|
||||
Take a URL string, and return an object.
|
||||
|
||||
Pass `true` as the second argument to also parse
|
||||
the query string using the `querystring` module.
|
||||
|
||||
Pass `true` as the third argument to treat `//foo/bar` as
|
||||
`{ host: 'foo', pathname: '/bar' }` rather than
|
||||
`{ pathname: '//foo/bar' }`.
|
||||
|
||||
### url.format(urlObj)
|
||||
|
||||
Take a parsed URL object, and return a formatted URL string.
|
||||
|
||||
@@ -16,7 +16,7 @@ output `string` immediately to `stderr`.
|
||||
|
||||
Output with timestamp on `stdout`.
|
||||
|
||||
require('util').log('Timestmaped message.');
|
||||
require('util').log('Timestamped message.');
|
||||
|
||||
|
||||
### util.inspect(object, showHidden=false, depth=2)
|
||||
|
||||
@@ -126,6 +126,15 @@ h4 + h4 {
|
||||
margin: 0 0 0.5em;
|
||||
}
|
||||
|
||||
h3 a,
|
||||
h4 a {
|
||||
font-size: 0.8em;
|
||||
float: right;
|
||||
color: #000;
|
||||
text-decoration: none;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.125em;
|
||||
line-height: 1.4em;
|
||||
@@ -232,4 +241,4 @@ a.octothorpe {
|
||||
h5:hover > a.octothorpe,
|
||||
h6:hover > a.octothorpe {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
BIN
doc/favicon.ico
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.1 KiB |
@@ -24,14 +24,16 @@
|
||||
<div id="toc">
|
||||
<ol>
|
||||
<li><a href="#download">Download</a></li>
|
||||
<li><a href="https://github.com/joyent/node/raw/v0.4/ChangeLog">ChangeLog</a></li>
|
||||
<li><a href="https://github.com/joyent/node/wiki/ChangeLog">ChangeLog</a></li>
|
||||
<li><a href="#about">About</a></li>
|
||||
<li><a href="http://nodejs.org/docs/v0.4.8/api">v0.4.8 docs</a></li>
|
||||
<li><a href="http://nodejs.org/docs/v0.4.12/api">v0.4.12 docs</a></li>
|
||||
<li><a href="http://nodejs.org/docs/v0.5.6/api">v0.5.6 docs</a></li>
|
||||
<br/>
|
||||
<li><a href="https://github.com/joyent/node/wiki">Wiki</a></li>
|
||||
<li><a href="http://blog.nodejs.org/">Blog</a></li>
|
||||
<li><a href="https://github.com/joyent/node/wiki/Community">Community</a></li>
|
||||
<li><a href="http://chat.nodejs.org/">Demo</a></li>
|
||||
<li><a href="/logos/">Logos</a></li>
|
||||
<li><a href="http://jobs.nodejs.org/">Jobs</a></li>
|
||||
<ol><!-- JOBS --><!-- JOBS --></ol>
|
||||
</ol>
|
||||
@@ -39,6 +41,7 @@
|
||||
<div id="content">
|
||||
|
||||
<!-- <h1><a href="http://nodejs.org/">Node</a></h1> -->
|
||||
<br /><br />
|
||||
<img id="logo" src="logo.png" alt="node.js"/>
|
||||
|
||||
<p id="introduction">
|
||||
@@ -107,11 +110,19 @@ server.listen(1337, "127.0.0.1");
|
||||
<a href="http://github.com/joyent/node/tree/master">git repo</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
2011.05.20
|
||||
<a href="http://nodejs.org/dist/node-v0.4.8.tar.gz">node-v0.4.8.tar.gz</a>
|
||||
(<a href="http://nodejs.org/docs/v0.4.8/api/index.html">Documentation</a>)
|
||||
</p>
|
||||
<p>2011.09.15 v0.4.12 (stable)
|
||||
<ul class="release">
|
||||
<li><a href="http://nodejs.org/dist/node-v0.4.12.tar.gz"><code>node-v0.4.12.tar.gz</code> Source Code</a>
|
||||
<li><a href="http://nodejs.org/docs/v0.4.12/api/index.html">Documentation</a>
|
||||
</ul>
|
||||
|
||||
<p>2011.09.09 v0.5.6 (unstable)
|
||||
<ul class="release">
|
||||
<li><a href="http://nodejs.org/dist/v0.5.6/node-v0.5.6.tar.gz"><code>node-v0.5.6.tar.gz</code> Source code</a>
|
||||
<li><a href="http://nodejs.org/dist/v0.5.6/node.exe"><code>node.exe</code> Windows executable</a>
|
||||
<li><a href="http://nodejs.org/docs/v0.5.6/api/index.html">Documentation</a>
|
||||
</ul>
|
||||
|
||||
|
||||
<p>Historical: <a href="http://nodejs.org/dist">versions</a>, <a href="http://nodejs.org/docs">docs</a></p>
|
||||
|
||||
@@ -183,13 +194,8 @@ server.listen(1337, "127.0.0.1");
|
||||
But what about multiple-processor concurrency? Aren't threads
|
||||
necessary to scale programs to multi-core computers?
|
||||
</i>
|
||||
Processes are necessary to scale to multi-core computers, not
|
||||
memory-sharing threads. The fundamentals of scalable systems are
|
||||
fast networking and non-blocking design—the rest is message
|
||||
passing. In future versions, Node will be able to fork new
|
||||
processes (using the <a
|
||||
href="http://www.whatwg.org/specs/web-workers/current-work/"> Web
|
||||
Workers API </a>) which fits well into the current design.
|
||||
You can start new processes via <code>child_process.fork()</code>
|
||||
these other processes will be scheduled in parallel.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
||||
BIN
doc/logo.png
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 5.4 KiB |
82
doc/logos/index.html
Normal file
@@ -0,0 +1,82 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"><head>
|
||||
<style type="text/css">
|
||||
ul {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript" src="../sh_main.js"></script>
|
||||
<script type="text/javascript" src="../sh_javascript.js"></script>
|
||||
<link type="image/x-icon" rel="icon" href="http://nodejs.org/favicon.ico">
|
||||
<link type="image/x-icon" rel="shortcut icon" href="../node-favicon.png">
|
||||
<link type="text/css" rel="stylesheet" href="../pipe.css">
|
||||
<link type="text/css" rel="stylesheet" href="../sh_vim-dark.css">
|
||||
<link rel="alternate" type="application/rss+xml" title="node blog" href="http://feeds.feedburner.com/nodejs/123123123">
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<title>Node.js Logos</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="content">
|
||||
|
||||
<!-- <h1><a href="http://nodejs.org/">Node</a></h1> -->
|
||||
<br />
|
||||
<br />
|
||||
<img src="../logo.png" alt="node.js" width="420" height="111" id="logo">
|
||||
<p>To echo the evolutionary nature of Node, we've added some punch and playfulness to its identity. All it needs now is a good home with you, download and have fun!</p>
|
||||
<h2>Logo Downloads</h2>
|
||||
<table border="0" cellspacing="0" cellpadding="10">
|
||||
<tr>
|
||||
<td bgcolor="#FFFFFF"><a href="nodejs-light.eps"><img src="nodejs.png" alt="Node.js dark" width="212" height="114" border="0" /></a></td>
|
||||
<td bgcolor="#46483E"><a href="nodejs-dark.eps"><img src="nodejs-dark.png" alt="Node.js dark" width="212" height="114" border="0" /></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="nodejs-light.eps">Node.js standard EPS</a></td>
|
||||
<td><a href="nodejs-dark.eps">Node.js reversed EPS</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td bgcolor="#8BC84B"><a href="nodejs-green.eps"><img src="nodejs-green.png" alt="Node.js dark" width="212" height="114" border="0" /></a><a href="nodejs-dark.eps"></a></td>
|
||||
<td bgcolor="#ffffff"><a href="nodejs-black.eps"><img src="nodejs-black.png" alt="Node.js dark" width="212" height="114" border="0" /></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="nodejs-green.eps">Node.js bright EPS</a></td>
|
||||
<td><a href="nodejs-black.eps">Node.js 1 color EPS</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2>Desktop Background</h2>
|
||||
<p><img src="monitor.png" width="525" height="398" alt="Screensavers" /></p>
|
||||
<p>Select your screen resolution:<a href="nodejs-1024x768.png"><br />
|
||||
<span class="desktops">1024 x 768</span></a><span class="desktops"> | <a href="nodejs-1280x1024.png">1280 x 1024</a> | <a href="nodejs-1440x900.png">1440 x 900</a> | <a href="nodejs-1920x1200.png">1920 x 1200</a> | <a href="nodejs-2560x1440.png">2560 x 1440</a></span></p>
|
||||
|
||||
<h2 id="video"> </h2>
|
||||
<p></p>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div style="float: right;"></div>
|
||||
|
||||
<a href="http://no.de/"><img src="../sponsored.png" height="58" width="120"></a>
|
||||
|
||||
<div style="clear: both; font-size: 8pt">
|
||||
Copyright 2010 Joyent, Inc
|
||||
<br>
|
||||
Node.js is a trademark of Joyent, Inc.
|
||||
See the <a href="http://nodejs.org/trademark-policy.pdf">trademark policy</a>
|
||||
for more information.
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ?
|
||||
"https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script><script src="../ga.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var pageTracker = _gat._getTracker("UA-10874194-2");
|
||||
pageTracker._trackPageview();
|
||||
} catch(err) {}</script>
|
||||
<script type="text/javascript">highlight(undefined, undefined, 'pre');</script>
|
||||
|
||||
|
||||
</body></html>
|
||||
BIN
doc/logos/monitor.png
Normal file
|
After Width: | Height: | Size: 128 KiB |
BIN
doc/logos/node-favicon.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
doc/logos/nodejs-1024x768.png
Normal file
|
After Width: | Height: | Size: 482 KiB |
BIN
doc/logos/nodejs-1280x1024.png
Normal file
|
After Width: | Height: | Size: 798 KiB |
BIN
doc/logos/nodejs-1440x900.png
Normal file
|
After Width: | Height: | Size: 821 KiB |
BIN
doc/logos/nodejs-1920x1200.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
doc/logos/nodejs-2560x1440.png
Normal file
|
After Width: | Height: | Size: 2.1 MiB |
BIN
doc/logos/nodejs-black.eps
Normal file
BIN
doc/logos/nodejs-black.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
doc/logos/nodejs-dark.eps
Normal file
BIN
doc/logos/nodejs-dark.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
doc/logos/nodejs-green.eps
Normal file
BIN
doc/logos/nodejs-green.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
doc/logos/nodejs-light.eps
Normal file
BIN
doc/logos/nodejs.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
58
doc/pipe.css
@@ -1,21 +1,25 @@
|
||||
html {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #22252a;
|
||||
color: #eee;
|
||||
font-size: 14pt;
|
||||
line-height: 150%;
|
||||
font-family: times, Times New Roman, times-roman, georgia, serif;
|
||||
max-width: 30em;
|
||||
margin: 0 0 5em 9em;
|
||||
background: #353129;
|
||||
color: #eee;
|
||||
font-size: 14pt;
|
||||
line-height: 150%;
|
||||
font-family: Georgia, "Times New Roman", Times, serif;
|
||||
max-width: 30em;
|
||||
margin: 0 0 5em 9em;
|
||||
}
|
||||
img {
|
||||
padding: 5em 0;
|
||||
border: 0;
|
||||
border: 0;
|
||||
}
|
||||
#toc {
|
||||
position: absolute;
|
||||
top: 2em;
|
||||
left: 0;
|
||||
width: 10em;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: 12pt;
|
||||
line-height: 150%;
|
||||
}
|
||||
@@ -35,11 +39,17 @@ img {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
#toc a { color: #aaa; }
|
||||
#toc a {
|
||||
color: #8BC84B;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
color: #B0C4DE;
|
||||
margin: 2em 0;
|
||||
color: #CCD2BC;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
margin-top: 2em;
|
||||
margin-right: 0;
|
||||
margin-bottom: 10px;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
#toc ol ol {
|
||||
@@ -56,14 +66,17 @@ h1 a, h2 a, h3 a, h4 a
|
||||
}
|
||||
|
||||
pre, code {
|
||||
font-family: monospace;
|
||||
font-size: 13pt;
|
||||
color: #eee0e0;
|
||||
font-family: Monaco, 'Andale Mono', 'Lucida Console', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif;
|
||||
;
|
||||
font-size: 11pt;
|
||||
color: #C3CC88;
|
||||
}
|
||||
|
||||
pre {
|
||||
padding-left: 1em;
|
||||
border-left: 1px solid #444;
|
||||
padding-left: 1em;
|
||||
border-left-width: 1px;
|
||||
border-left-style: solid;
|
||||
border-left-color: #8BC84B;
|
||||
}
|
||||
|
||||
dd {
|
||||
@@ -71,11 +84,20 @@ dd {
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
a { color: #cd5; text-decoration: none; }
|
||||
a {
|
||||
color: #8BC84B;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover { text-decoration: underline; }
|
||||
|
||||
.highlight {
|
||||
background: #733;
|
||||
padding: 0.2em 0;
|
||||
}
|
||||
.desktops {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.release {
|
||||
margin: 0 0 0 2em;
|
||||
}
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
.sh_sourceCode {
|
||||
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.sh_sourceCode .sh_symbol , .sh_sourceCode .sh_cbracket {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.sh_sourceCode .sh_keyword {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.sh_sourceCode .sh_string, .sh_sourceCode .sh_regexp, .sh_sourceCode .sh_number,
|
||||
.sh_sourceCode .sh_specialchar
|
||||
{
|
||||
color: #B0C4DE;
|
||||
}
|
||||
|
||||
.sh_sourceCode .sh_comment {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.sh_sourceCode {
|
||||
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.sh_sourceCode .sh_symbol , .sh_sourceCode .sh_cbracket {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.sh_sourceCode .sh_keyword {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.sh_sourceCode .sh_string, .sh_sourceCode .sh_regexp, .sh_sourceCode .sh_number,
|
||||
.sh_sourceCode .sh_specialchar
|
||||
{
|
||||
color: #B9CCC5;
|
||||
}
|
||||
|
||||
.sh_sourceCode .sh_comment {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 5.2 KiB |
@@ -1,7 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{{section}}Node.js Manual & Documentation</title>
|
||||
<meta charset="UTF-8" />
|
||||
<title>{{section}}Node.js v0.4.12 Manual & Documentation</title>
|
||||
<link type="image/x-icon" rel="icon" href="/favicon.ico" />
|
||||
<link type="image/x-icon" rel="shortcut icon" href="/favicon.ico" />
|
||||
<link rel="stylesheet" href="assets/style.css" type="text/css" media="all" />
|
||||
@@ -10,7 +11,7 @@
|
||||
<body>
|
||||
<div id="container">
|
||||
<header>
|
||||
<h1>Node.js Manual & Documentation</h1>
|
||||
<h1>Node.js v0.4.12 Manual & Documentation</h1>
|
||||
<div id="gtoc">
|
||||
<p><a href="index.html">Index</a> | <a href="all.html">View on single page</a></p>
|
||||
</div>
|
||||
@@ -22,4 +23,4 @@
|
||||
<script type="text/javascript" src="assets/sh_javascript.min.js"></script>
|
||||
<script type="text/javascript">highlight(undefined, undefined, 'pre');</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -998,7 +998,7 @@ Interface.prototype.yesNoQuestion = function(prompt, cb) {
|
||||
cb(false);
|
||||
} else {
|
||||
console.log('Please answer y or n.');
|
||||
self.restartQuestion(cb);
|
||||
self.yesNoQuestion(prompt, cb);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -56,9 +56,21 @@ assert.AssertionError.prototype.toString = function() {
|
||||
return [this.name + ':', this.message].join(' ');
|
||||
} else {
|
||||
return [this.name + ':',
|
||||
JSON.stringify(this.expected),
|
||||
JSON.stringify(this.expected, replacer),
|
||||
this.operator,
|
||||
JSON.stringify(this.actual)].join(' ');
|
||||
JSON.stringify(this.actual, replacer)].join(' ');
|
||||
}
|
||||
function replacer(key, value) {
|
||||
if (value === undefined) {
|
||||
return '' + value;
|
||||
}
|
||||
if (typeof value === 'number' && (isNaN(value) || !isFinite(value))) {
|
||||
return value.toString();
|
||||
}
|
||||
if (typeof value === 'function' || value instanceof RegExp) {
|
||||
return value.toString();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -123,6 +123,15 @@ SlowBuffer.prototype.slice = function(start, end) {
|
||||
};
|
||||
|
||||
|
||||
function coerce(length) {
|
||||
// Coerce length to a number (possibly NaN), round up
|
||||
// in case it's fractional (e.g. 123.456) then do a
|
||||
// double negate to coerce a NaN to 0. Easy, right?
|
||||
length = ~~Math.ceil(+length);
|
||||
return length < 0 ? 0 : length;
|
||||
}
|
||||
|
||||
|
||||
// Buffer
|
||||
|
||||
function Buffer(subject, encoding, offset) {
|
||||
@@ -134,14 +143,14 @@ function Buffer(subject, encoding, offset) {
|
||||
|
||||
// Are we slicing?
|
||||
if (typeof offset === 'number') {
|
||||
this.length = encoding;
|
||||
this.length = coerce(encoding);
|
||||
this.parent = subject;
|
||||
this.offset = offset;
|
||||
} else {
|
||||
// Find the length
|
||||
switch (type = typeof subject) {
|
||||
case 'number':
|
||||
this.length = subject;
|
||||
this.length = coerce(subject);
|
||||
break;
|
||||
|
||||
case 'string':
|
||||
@@ -149,7 +158,7 @@ function Buffer(subject, encoding, offset) {
|
||||
break;
|
||||
|
||||
case 'object': // Assume object is an array
|
||||
this.length = subject.length;
|
||||
this.length = coerce(subject.length);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -110,8 +110,8 @@ exports.createHmac = function(hmac, key) {
|
||||
|
||||
|
||||
exports.Cipher = Cipher;
|
||||
exports.createCipher = function(cipher, key) {
|
||||
return (new Cipher).init(cipher, key);
|
||||
exports.createCipher = function(cipher, password) {
|
||||
return (new Cipher).init(cipher, password);
|
||||
};
|
||||
|
||||
|
||||
@@ -121,8 +121,8 @@ exports.createCipheriv = function(cipher, key, iv) {
|
||||
|
||||
|
||||
exports.Decipher = Decipher;
|
||||
exports.createDecipher = function(cipher, key) {
|
||||
return (new Decipher).init(cipher, key);
|
||||
exports.createDecipher = function(cipher, password) {
|
||||
return (new Decipher).init(cipher, password);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -542,7 +542,7 @@ var path = require('path'),
|
||||
isWindows = process.platform === 'win32';
|
||||
|
||||
if (isWindows) {
|
||||
// Node doesn't support symlinks / lstat on windows. Hence realpatch is just
|
||||
// Node doesn't support symlinks / lstat on windows. Hence realpath is just
|
||||
// the same as path.resolve that fails if the path doesn't exists.
|
||||
|
||||
// windows version
|
||||
|
||||
30
lib/http.js
@@ -284,6 +284,7 @@ IncomingMessage.prototype._addHeaderLine = function(field, value) {
|
||||
case 'connection':
|
||||
case 'cookie':
|
||||
case 'pragma':
|
||||
case 'link':
|
||||
if (field in dest) {
|
||||
dest[field] += ', ' + value;
|
||||
} else {
|
||||
@@ -608,7 +609,6 @@ OutgoingMessage.prototype.write = function(chunk, encoding) {
|
||||
if (typeof(chunk) === 'string') {
|
||||
len = Buffer.byteLength(chunk, encoding);
|
||||
var chunk = len.toString(16) + CRLF + chunk + CRLF;
|
||||
debug('string chunk = ' + util.inspect(chunk));
|
||||
ret = this._send(chunk, encoding);
|
||||
} else {
|
||||
// buffer
|
||||
@@ -647,10 +647,19 @@ OutgoingMessage.prototype.addTrailers = function(headers) {
|
||||
|
||||
|
||||
OutgoingMessage.prototype.end = function(data, encoding) {
|
||||
if (this.finished) {
|
||||
return false;
|
||||
}
|
||||
if (!this._header) {
|
||||
this._implicitHeader();
|
||||
}
|
||||
|
||||
if (data && !this._hasBody) {
|
||||
console.error('This type of response MUST NOT have a body. ' +
|
||||
'Ignoring data passed to end().');
|
||||
data = false;
|
||||
}
|
||||
|
||||
var ret;
|
||||
|
||||
var hot = this._headerSent === false &&
|
||||
@@ -666,6 +675,7 @@ OutgoingMessage.prototype.end = function(data, encoding) {
|
||||
// res.writeHead();
|
||||
// res.end(blah);
|
||||
// HACKY.
|
||||
|
||||
if (this.chunkedEncoding) {
|
||||
var l = Buffer.byteLength(data, encoding).toString(16);
|
||||
ret = this.connection.write(this._header + l + CRLF +
|
||||
@@ -797,6 +807,7 @@ ServerResponse.prototype.writeHead = function(statusCode) {
|
||||
reasonPhrase = STATUS_CODES[statusCode] || 'unknown';
|
||||
headerIndex = 1;
|
||||
}
|
||||
this.statusCode = statusCode;
|
||||
|
||||
var obj = arguments[headerIndex];
|
||||
|
||||
@@ -1151,12 +1162,6 @@ Agent.prototype.appendMessage = function(options) {
|
||||
this.queue.push(req);
|
||||
req._queue = this.queue;
|
||||
|
||||
/*
|
||||
req.on('finish', function () {
|
||||
self._cycle();
|
||||
});
|
||||
*/
|
||||
|
||||
this._cycle();
|
||||
|
||||
return req;
|
||||
@@ -1338,7 +1343,10 @@ Agent.prototype._establishNewConnection = function() {
|
||||
debug('AGENT socket keep-alive');
|
||||
}
|
||||
|
||||
req.detachSocket(socket);
|
||||
// The socket may already be detached and destroyed by an abort call
|
||||
if (socket._httpMessage) {
|
||||
req.detachSocket(socket);
|
||||
}
|
||||
|
||||
assert(!socket._httpMessage);
|
||||
|
||||
@@ -1373,8 +1381,6 @@ Agent.prototype._cycle = function() {
|
||||
var first = this.queue[0];
|
||||
if (!first) return;
|
||||
|
||||
var haveConnectingSocket = false;
|
||||
|
||||
// First try to find an available socket.
|
||||
for (var i = 0; i < this.sockets.length; i++) {
|
||||
var socket = this.sockets[i];
|
||||
@@ -1394,13 +1400,11 @@ Agent.prototype._cycle = function() {
|
||||
self._cycle(); // try to dispatch another
|
||||
return;
|
||||
}
|
||||
|
||||
if (socket._httpConnecting) haveConnectingSocket = true;
|
||||
}
|
||||
|
||||
// If no sockets are connecting, and we have space for another we should
|
||||
// be starting a new connection to handle this request.
|
||||
if (!haveConnectingSocket && this.sockets.length < this.maxSockets) {
|
||||
if (this.sockets.length < this.maxSockets) {
|
||||
this._establishNewConnection();
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,15 @@ var runInThisContext = Script.runInThisContext;
|
||||
var runInNewContext = Script.runInNewContext;
|
||||
var assert = require('assert').ok;
|
||||
|
||||
|
||||
// If obj.hasOwnProperty has been overridden, then calling
|
||||
// obj.hasOwnProperty(prop) will break.
|
||||
// See: https://github.com/joyent/node/issues/1707
|
||||
function hasOwnProperty(obj, prop) {
|
||||
return Object.prototype.hasOwnProperty.call(obj, prop);
|
||||
}
|
||||
|
||||
|
||||
function Module(id, parent) {
|
||||
this.id = id;
|
||||
this.exports = {};
|
||||
@@ -85,7 +94,7 @@ function statPath(path) {
|
||||
var packageCache = {};
|
||||
|
||||
function readPackage(requestPath) {
|
||||
if (packageCache.hasOwnProperty(requestPath)) {
|
||||
if (hasOwnProperty(packageCache, requestPath)) {
|
||||
return packageCache[requestPath];
|
||||
}
|
||||
|
||||
@@ -199,12 +208,7 @@ Module._nodeModulePaths = function(from) {
|
||||
var paths = [];
|
||||
var parts = from.split(splitRe);
|
||||
|
||||
var root = parts.indexOf('node_modules') - 1;
|
||||
if (root < 0) root = 0;
|
||||
|
||||
var tip = parts.length - 1;
|
||||
|
||||
for (var tip = parts.length - 1; tip >= root; tip --) {
|
||||
for (var tip = parts.length - 1; tip >= 0; tip --) {
|
||||
// don't search in .../node_modules/node_modules
|
||||
if (parts[tip] === 'node_modules') continue;
|
||||
var dir = parts.slice(0, tip + 1).concat('node_modules').join(joiner);
|
||||
|
||||
44
lib/net.js
@@ -349,11 +349,13 @@ Socket.prototype.write = function(data /* [encoding], [fd], [cb] */) {
|
||||
if (!this._writeQueueCallbacks[last]) {
|
||||
this._writeQueueCallbacks[last] = cb;
|
||||
} else {
|
||||
// awful
|
||||
this._writeQueueCallbacks[last] = function() {
|
||||
this._writeQueueCallbacks[last]();
|
||||
cb();
|
||||
};
|
||||
var original = this._writeQueueCallbacks[last];
|
||||
|
||||
if (Array.isArray(original)) {
|
||||
original.push(cb);
|
||||
} else {
|
||||
this._writeQueueCallbacks[last] = [ original, cb ];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -409,16 +411,10 @@ Socket.prototype._writeOut = function(data, encoding, fd, cb) {
|
||||
allocNewPool();
|
||||
}
|
||||
|
||||
if (!encoding || encoding == 'utf8' || encoding == 'utf-8') {
|
||||
// default to utf8
|
||||
bytesWritten = pool.write(data, 'utf8', pool.used);
|
||||
charsWritten = Buffer._charsWritten;
|
||||
} else {
|
||||
bytesWritten = pool.write(data, encoding, pool.used);
|
||||
charsWritten = bytesWritten;
|
||||
}
|
||||
bytesWritten = pool.write(data, encoding, pool.used);
|
||||
charsWritten = Buffer._charsWritten;
|
||||
|
||||
if (encoding && data.length > 0) {
|
||||
if (data.length > 0) {
|
||||
assert(bytesWritten > 0);
|
||||
}
|
||||
|
||||
@@ -470,7 +466,15 @@ Socket.prototype._writeOut = function(data, encoding, fd, cb) {
|
||||
if (queuedData) {
|
||||
return false;
|
||||
} else {
|
||||
if (cb) cb();
|
||||
if (cb) {
|
||||
if (Array.isArray(cb)) {
|
||||
for (var i = 0; i < cb.length; i++) {
|
||||
if (cb[i]) cb[i]();
|
||||
}
|
||||
} else {
|
||||
cb();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -717,7 +721,13 @@ Socket.prototype.connect = function() {
|
||||
// TCP
|
||||
require('dns').lookup(arguments[1], function(err, ip, addressType) {
|
||||
if (err) {
|
||||
self.emit('error', err);
|
||||
// net.createConnection() creates a net.Socket object and
|
||||
// immediately calls net.Socket.connect() on it (that's us).
|
||||
// There are no event listeners registered yet so defer the
|
||||
// error event to the next tick.
|
||||
process.nextTick(function() {
|
||||
self.emit('error', err);
|
||||
});
|
||||
} else {
|
||||
timers.active(self);
|
||||
self.type = addressType == 4 ? 'tcp4' : 'tcp6';
|
||||
@@ -1047,7 +1057,7 @@ Server.prototype.listen = function() {
|
||||
if (err.errno == ENOENT) {
|
||||
self._doListen(path);
|
||||
} else {
|
||||
throw r;
|
||||
throw err;
|
||||
}
|
||||
} else {
|
||||
if (!r.isSocket()) {
|
||||
|
||||
@@ -25,6 +25,14 @@ var QueryString = exports;
|
||||
var urlDecode = process.binding('http_parser').urlDecode;
|
||||
|
||||
|
||||
// If obj.hasOwnProperty has been overridden, then calling
|
||||
// obj.hasOwnProperty(prop) will break.
|
||||
// See: https://github.com/joyent/node/issues/1707
|
||||
function hasOwnProperty(obj, prop) {
|
||||
return Object.prototype.hasOwnProperty.call(obj, prop);
|
||||
}
|
||||
|
||||
|
||||
function charCode(c) {
|
||||
return c.charCodeAt(0);
|
||||
}
|
||||
@@ -166,7 +174,7 @@ QueryString.parse = QueryString.decode = function(qs, sep, eq) {
|
||||
var k = QueryString.unescape(x[0], true);
|
||||
var v = QueryString.unescape(x.slice(1).join(eq), true);
|
||||
|
||||
if (!(k in obj)) {
|
||||
if (!hasOwnProperty(obj, k)) {
|
||||
obj[k] = v;
|
||||
} else if (!Array.isArray(obj[k])) {
|
||||
obj[k] = [obj[k], v];
|
||||
|
||||
10
lib/repl.js
@@ -46,6 +46,14 @@ var path = require('path');
|
||||
var fs = require('fs');
|
||||
var rl = require('readline');
|
||||
|
||||
// If obj.hasOwnProperty has been overridden, then calling
|
||||
// obj.hasOwnProperty(prop) will break.
|
||||
// See: https://github.com/joyent/node/issues/1707
|
||||
function hasOwnProperty(obj, prop) {
|
||||
return Object.prototype.hasOwnProperty.call(obj, prop);
|
||||
}
|
||||
|
||||
|
||||
var context;
|
||||
|
||||
var disableColors = true;
|
||||
@@ -446,7 +454,7 @@ REPLServer.prototype.complete = function(line) {
|
||||
group.sort();
|
||||
for (var j = 0; j < group.length; j++) {
|
||||
c = group[j];
|
||||
if (!uniq.hasOwnProperty(c)) {
|
||||
if (!hasOwnProperty(uniq, c)) {
|
||||
completions.push(c);
|
||||
uniq[c] = true;
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ Stream.prototype.pipe = function(dest, options) {
|
||||
// don't leave dangling pipes when there are errors.
|
||||
function onerror(er) {
|
||||
cleanup();
|
||||
if (this.listeners('error').length === 1) {
|
||||
if (this.listeners('error').length === 0) {
|
||||
throw er; // Unhandled stream error in pipe.
|
||||
}
|
||||
}
|
||||
|
||||
53
lib/tls.js
@@ -52,6 +52,7 @@ function CryptoStream(pair) {
|
||||
this.readable = this.writable = true;
|
||||
|
||||
this._paused = false;
|
||||
this._needDrain = false;
|
||||
this._pending = [];
|
||||
this._pendingCallbacks = [];
|
||||
this._pendingBytes = 0;
|
||||
@@ -86,7 +87,7 @@ CryptoStream.prototype.write = function(data /* , encoding, cb */) {
|
||||
data = new Buffer(data, encoding);
|
||||
}
|
||||
|
||||
debug('clearIn data');
|
||||
debug((this === this.pair.cleartext ? 'clear' : 'encrypted') + 'In data');
|
||||
|
||||
this._pending.push(data);
|
||||
this._pendingCallbacks.push(cb);
|
||||
@@ -95,7 +96,26 @@ CryptoStream.prototype.write = function(data /* , encoding, cb */) {
|
||||
this.pair._writeCalled = true;
|
||||
this.pair.cycle();
|
||||
|
||||
return this._pendingBytes < 128 * 1024;
|
||||
// In the following cases, write() should return a false,
|
||||
// then this stream should eventually emit 'drain' event.
|
||||
//
|
||||
// 1. There are pending data more than 128k bytes.
|
||||
// 2. A forward stream shown below is paused.
|
||||
// A) EncryptedStream for CleartextStream.write().
|
||||
// B) CleartextStream for EncryptedStream.write().
|
||||
//
|
||||
if (!this._needDrain) {
|
||||
if (this._pendingBytes >= 128 * 1024) {
|
||||
this._needDrain = true;
|
||||
} else {
|
||||
if (this === this.pair.cleartext) {
|
||||
this._needDrain = this.pair.encrypted._paused;
|
||||
} else {
|
||||
this._needDrain = this.pair.cleartext._paused;
|
||||
}
|
||||
}
|
||||
}
|
||||
return !this._needDrain;
|
||||
};
|
||||
|
||||
|
||||
@@ -380,11 +400,25 @@ CryptoStream.prototype._pull = function() {
|
||||
assert(rv === tmp.length);
|
||||
}
|
||||
|
||||
// If we've cleared all of incoming encrypted data, emit drain.
|
||||
if (havePending && this._pending.length === 0) {
|
||||
debug('drain');
|
||||
this.emit('drain');
|
||||
if (this.__destroyOnDrain) this.end();
|
||||
// If pending data has cleared, 'drain' event should be emitted
|
||||
// after write() returns a false.
|
||||
// Except when a forward stream shown below is paused.
|
||||
// A) EncryptedStream for CleartextStream._pull().
|
||||
// B) CleartextStream for EncryptedStream._pull().
|
||||
//
|
||||
if (this._needDrain && this._pending.length === 0) {
|
||||
var paused;
|
||||
if (this === this.pair.cleartext) {
|
||||
paused = this.pair.encrypted._paused;
|
||||
} else {
|
||||
paused = this.pair.cleartext._paused;
|
||||
}
|
||||
if (!paused) {
|
||||
debug('drain');
|
||||
process.nextTick(this.emit.bind(this, 'drain'));
|
||||
this._needDrain = false;
|
||||
if (this.__destroyOnDrain) this.end();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -496,7 +530,10 @@ function SecurePair(credentials, isServer, requestCert, rejectUnauthorized) {
|
||||
this.encrypted = new EncryptedStream(this);
|
||||
|
||||
process.nextTick(function() {
|
||||
self.ssl.start();
|
||||
/* The Connection may be destroyed by an abort call */
|
||||
if (self.ssl) {
|
||||
self.ssl.start();
|
||||
}
|
||||
self.cycle();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -71,14 +71,14 @@ function ReadStream(fd) {
|
||||
} else {
|
||||
// Nobody's watching anyway
|
||||
self.removeListener('data', onData);
|
||||
self.on('newlistener', onNewListener);
|
||||
self.on('newListener', onNewListener);
|
||||
}
|
||||
}
|
||||
|
||||
function onNewListener(event) {
|
||||
if (event == 'keypress') {
|
||||
self.on('data', onData);
|
||||
self.removeListener('newlistener', onNewListener);
|
||||
self.removeListener('newListener', onNewListener);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -331,7 +331,7 @@ WriteStream.prototype.cursorTo = function(x, y) {
|
||||
if (typeof x !== 'number')
|
||||
throw new Error("Can't set cursor row without also setting it's column");
|
||||
|
||||
if (typeof x === 'number') {
|
||||
if (typeof y !== 'number') {
|
||||
this.write('\x1b[' + (x + 1) + 'G');
|
||||
} else {
|
||||
this.write('\x1b[' + (y + 1) + ';' + (x + 1) + 'H');
|
||||
|
||||
@@ -44,8 +44,8 @@ var protocolPattern = /^([a-z0-9]+:)/i,
|
||||
.concat(unwise).concat(autoEscape),
|
||||
nonAuthChars = ['/', '@', '?', '#'].concat(delims),
|
||||
hostnameMaxLen = 255,
|
||||
hostnamePartPattern = /^[a-zA-Z0-9][a-z0-9A-Z-]{0,62}$/,
|
||||
hostnamePartStart = /^([a-zA-Z0-9][a-z0-9A-Z-]{0,62})(.*)$/,
|
||||
hostnamePartPattern = /^[a-zA-Z0-9][a-z0-9A-Z_-]{0,62}$/,
|
||||
hostnamePartStart = /^([a-zA-Z0-9][a-z0-9A-Z_-]{0,62})(.*)$/,
|
||||
// protocols that can allow "unsafe" and "unwise" chars.
|
||||
unsafeProtocol = {
|
||||
'javascript': true,
|
||||
@@ -54,9 +54,7 @@ var protocolPattern = /^([a-z0-9]+:)/i,
|
||||
// protocols that never have a hostname.
|
||||
hostlessProtocol = {
|
||||
'javascript': true,
|
||||
'javascript:': true,
|
||||
'file': true,
|
||||
'file:': true
|
||||
'javascript:': true
|
||||
},
|
||||
// protocols that always have a path component.
|
||||
pathedProtocol = {
|
||||
|
||||
18
lib/util.js
@@ -284,15 +284,8 @@ function isArray(ar) {
|
||||
|
||||
|
||||
function isRegExp(re) {
|
||||
var s = '' + re;
|
||||
return re instanceof RegExp || // easy case
|
||||
// duck-type for context-switching evalcx case
|
||||
typeof(re) === 'function' &&
|
||||
re.constructor.name === 'RegExp' &&
|
||||
re.compile &&
|
||||
re.test &&
|
||||
re.exec &&
|
||||
s.match(/^\/.*\/[gim]{0,3}$/);
|
||||
return re instanceof RegExp ||
|
||||
(typeof re === 'object' && Object.prototype.toString.call(re) === '[object RegExp]');
|
||||
}
|
||||
|
||||
|
||||
@@ -423,6 +416,11 @@ exports.pump = function(readStream, writeStream, callback) {
|
||||
exports.inherits = function(ctor, superCtor) {
|
||||
ctor.super_ = superCtor;
|
||||
ctor.prototype = Object.create(superCtor.prototype, {
|
||||
constructor: { value: ctor, enumerable: false }
|
||||
constructor: {
|
||||
value: ctor,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
configurable: true
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
# include <grp.h> /* getgrnam() */
|
||||
#endif
|
||||
|
||||
#include <platform.h>
|
||||
#include "platform.h"
|
||||
#include <node_buffer.h>
|
||||
#include <node_io_watcher.h>
|
||||
#include <node_net.h>
|
||||
@@ -1574,6 +1574,7 @@ typedef void (*extInit)(Handle<Object> exports);
|
||||
// DLOpen is node.dlopen(). Used to load 'module.node' dynamically shared
|
||||
// objects.
|
||||
Handle<Value> DLOpen(const v8::Arguments& args) {
|
||||
node_module_struct compat_mod;
|
||||
HandleScope scope;
|
||||
|
||||
if (args.Length() < 2) return Undefined();
|
||||
@@ -1616,10 +1617,13 @@ Handle<Value> DLOpen(const v8::Arguments& args) {
|
||||
// Get the init() function from the dynamically shared object.
|
||||
node_module_struct *mod = static_cast<node_module_struct *>(dlsym(handle, symstr));
|
||||
free(symstr);
|
||||
symstr = NULL;
|
||||
|
||||
// Error out if not found.
|
||||
if (mod == NULL) {
|
||||
/* Start Compatibility hack: Remove once everyone is using NODE_MODULE macro */
|
||||
node_module_struct compat_mod;
|
||||
memset(&compat_mod, 0, sizeof compat_mod);
|
||||
|
||||
mod = &compat_mod;
|
||||
mod->version = NODE_MODULE_VERSION;
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace node {
|
||||
|
||||
int Start (int argc, char *argv[]);
|
||||
|
||||
#define NODE_PSYMBOL(s) Persistent<String>::New(String::NewSymbol(s))
|
||||
#define NODE_PSYMBOL(s) v8::Persistent<v8::String>::New(v8::String::NewSymbol(s))
|
||||
|
||||
/* Converts a unixtime to V8 Date */
|
||||
#define NODE_UNIXTIME_V8(t) v8::Date::New(1000*static_cast<double>(t))
|
||||
|
||||
@@ -353,8 +353,13 @@
|
||||
}
|
||||
|
||||
var Module = NativeModule.require('module');
|
||||
var path = NativeModule.require('path');
|
||||
var cwd = process.cwd();
|
||||
|
||||
var rv = new Module()._compile('return eval(process._eval)', 'eval');
|
||||
var module = new Module('eval');
|
||||
module.filename = path.join(cwd, 'eval');
|
||||
module.paths = Module._nodeModulePaths(cwd);
|
||||
var rv = module._compile('return eval(process._eval)', 'eval');
|
||||
console.log(rv);
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <string.h> // memcpy
|
||||
|
||||
#ifdef __MINGW32__
|
||||
# include <platform.h>
|
||||
# include "platform.h"
|
||||
# include <platform_win32_winsock.h> // htons, htonl
|
||||
#endif
|
||||
|
||||
@@ -447,7 +447,15 @@ Handle<Value> Buffer::Utf8Write(const Arguments &args) {
|
||||
|
||||
size_t offset = args[1]->Uint32Value();
|
||||
|
||||
if (s->Length() > 0 && offset >= buffer->length_) {
|
||||
int length = s->Length();
|
||||
|
||||
if (length == 0) {
|
||||
constructor_template->GetFunction()->Set(chars_written_sym,
|
||||
Integer::New(0));
|
||||
return scope.Close(Integer::New(0));
|
||||
}
|
||||
|
||||
if (length > 0 && offset >= buffer->length_) {
|
||||
return ThrowException(Exception::TypeError(String::New(
|
||||
"Offset is out of bounds")));
|
||||
}
|
||||
@@ -468,7 +476,13 @@ Handle<Value> Buffer::Utf8Write(const Arguments &args) {
|
||||
constructor_template->GetFunction()->Set(chars_written_sym,
|
||||
Integer::New(char_written));
|
||||
|
||||
if (written > 0 && p[written-1] == '\0') written--;
|
||||
if (written > 0 && p[written-1] == '\0' && char_written == length) {
|
||||
uint16_t last_char;
|
||||
s->Write(&last_char, length - 1, 1, String::NO_HINTS);
|
||||
if (last_char != 0 || written > s->Utf8Length()) {
|
||||
written--;
|
||||
}
|
||||
}
|
||||
|
||||
return scope.Close(Integer::New(written));
|
||||
}
|
||||
@@ -541,6 +555,10 @@ Handle<Value> Buffer::AsciiWrite(const Arguments &args) {
|
||||
0,
|
||||
max_length,
|
||||
String::HINT_MANY_WRITES_EXPECTED);
|
||||
|
||||
constructor_template->GetFunction()->Set(chars_written_sym,
|
||||
Integer::New(written));
|
||||
|
||||
return scope.Close(Integer::New(written));
|
||||
}
|
||||
|
||||
@@ -628,6 +646,9 @@ Handle<Value> Buffer::Base64Write(const Arguments &args) {
|
||||
*dst++ = ((c & 0x03) << 6) | (d & 0x3F);
|
||||
}
|
||||
|
||||
constructor_template->GetFunction()->Set(chars_written_sym,
|
||||
Integer::New(s.length()));
|
||||
|
||||
return scope.Close(Integer::New(dst - start));
|
||||
}
|
||||
|
||||
@@ -653,9 +674,15 @@ Handle<Value> Buffer::BinaryWrite(const Arguments &args) {
|
||||
|
||||
char *p = (char*)buffer->data_ + offset;
|
||||
|
||||
size_t towrite = MIN((unsigned long) s->Length(), buffer->length_ - offset);
|
||||
size_t max_length = args[2]->IsUndefined() ? buffer->length_ - offset
|
||||
: args[2]->Uint32Value();
|
||||
max_length = MIN(s->Length(), MIN(buffer->length_ - offset, max_length));
|
||||
|
||||
int written = DecodeWrite(p, max_length, s, BINARY);
|
||||
|
||||
constructor_template->GetFunction()->Set(chars_written_sym,
|
||||
Integer::New(written));
|
||||
|
||||
int written = DecodeWrite(p, towrite, s, BINARY);
|
||||
return scope.Close(Integer::New(written));
|
||||
}
|
||||
|
||||
|
||||
@@ -164,7 +164,13 @@ Handle<Value> ChildProcess::Spawn(const Arguments& args) {
|
||||
if (args[4]->IsArray()) {
|
||||
// Set the custom file descriptor values (if any) for the child process
|
||||
Local<Array> custom_fds_handle = Local<Array>::Cast(args[4]);
|
||||
|
||||
int custom_fds_len = custom_fds_handle->Length();
|
||||
// Bound by 3.
|
||||
if (custom_fds_len > 3) {
|
||||
custom_fds_len = 3;
|
||||
}
|
||||
|
||||
for (int i = 0; i < custom_fds_len; i++) {
|
||||
if (custom_fds_handle->Get(i)->IsUndefined()) continue;
|
||||
Local<Integer> fd = custom_fds_handle->Get(i)->ToInteger();
|
||||
|
||||
@@ -42,6 +42,9 @@
|
||||
return ThrowException(Exception::TypeError(String::New("Not a string or buffer"))); \
|
||||
}
|
||||
|
||||
static const char *PUBLIC_KEY_PFX = "-----BEGIN PUBLIC KEY-----";
|
||||
static const int PUBLIC_KEY_PFX_LEN = strlen(PUBLIC_KEY_PFX);
|
||||
|
||||
namespace node {
|
||||
namespace crypto {
|
||||
|
||||
@@ -98,11 +101,23 @@ Handle<Value> SecureContext::Init(const Arguments& args) {
|
||||
String::Utf8Value sslmethod(args[0]->ToString());
|
||||
|
||||
if (strcmp(*sslmethod, "SSLv2_method") == 0) {
|
||||
#ifndef OPENSSL_NO_SSL2
|
||||
method = SSLv2_method();
|
||||
#else
|
||||
return ThrowException(Exception::Error(String::New("SSLv2 methods disabled")));
|
||||
#endif
|
||||
} else if (strcmp(*sslmethod, "SSLv2_server_method") == 0) {
|
||||
#ifndef OPENSSL_NO_SSL2
|
||||
method = SSLv2_server_method();
|
||||
#else
|
||||
return ThrowException(Exception::Error(String::New("SSLv2 methods disabled")));
|
||||
#endif
|
||||
} else if (strcmp(*sslmethod, "SSLv2_client_method") == 0) {
|
||||
#ifndef OPENSSL_NO_SSL2
|
||||
method = SSLv2_client_method();
|
||||
#else
|
||||
return ThrowException(Exception::Error(String::New("SSLv2 methods disabled")));
|
||||
#endif
|
||||
} else if (strcmp(*sslmethod, "SSLv3_method") == 0) {
|
||||
method = SSLv3_method();
|
||||
} else if (strcmp(*sslmethod, "SSLv3_server_method") == 0) {
|
||||
@@ -144,7 +159,7 @@ static BIO* LoadBIO (Handle<Value> v) {
|
||||
|
||||
HandleScope scope;
|
||||
|
||||
int r;
|
||||
int r = -1;
|
||||
|
||||
if (v->IsString()) {
|
||||
String::Utf8Value s(v->ToString());
|
||||
@@ -301,7 +316,7 @@ Handle<Value> SecureContext::SetCert(const Arguments& args) {
|
||||
String::New("SSL_CTX_use_certificate_chain")));
|
||||
}
|
||||
char string[120];
|
||||
ERR_error_string(err, string);
|
||||
ERR_error_string_n(err, string, sizeof string);
|
||||
return ThrowException(Exception::Error(String::New(string)));
|
||||
}
|
||||
|
||||
@@ -477,7 +492,10 @@ int Connection::HandleSSLError(const char* func, int rv) {
|
||||
|
||||
int err = SSL_get_error(ssl_, rv);
|
||||
|
||||
if (err == SSL_ERROR_WANT_WRITE) {
|
||||
if (err == SSL_ERROR_NONE) {
|
||||
return 0;
|
||||
|
||||
} else if (err == SSL_ERROR_WANT_WRITE) {
|
||||
DEBUG_PRINT("[%p] SSL: %s want write\n", ssl_, func);
|
||||
return 0;
|
||||
|
||||
@@ -486,14 +504,24 @@ int Connection::HandleSSLError(const char* func, int rv) {
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
static char ssl_error_buf[512];
|
||||
ERR_error_string_n(err, ssl_error_buf, sizeof(ssl_error_buf));
|
||||
|
||||
HandleScope scope;
|
||||
Local<Value> e = Exception::Error(String::New(ssl_error_buf));
|
||||
handle_->Set(String::New("error"), e);
|
||||
BUF_MEM* mem;
|
||||
BIO *bio;
|
||||
|
||||
DEBUG_PRINT("[%p] SSL: %s failed: (%d:%d) %s\n", ssl_, func, err, rv, ssl_error_buf);
|
||||
assert(err == SSL_ERROR_SSL || err == SSL_ERROR_SYSCALL);
|
||||
|
||||
// XXX We need to drain the error queue for this thread or else OpenSSL
|
||||
// has the possibility of blocking connections? This problem is not well
|
||||
// understood. And we should be somehow propagating these errors up
|
||||
// into JavaScript. There is no test which demonstrates this problem.
|
||||
// https://github.com/joyent/node/issues/1719
|
||||
if ((bio = BIO_new(BIO_s_mem()))) {
|
||||
ERR_print_errors(bio);
|
||||
BIO_get_mem_ptr(bio, &mem);
|
||||
Local<Value> e = Exception::Error(String::New(mem->data, mem->length));
|
||||
handle_->Set(String::New("error"), e);
|
||||
BIO_free(bio);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
@@ -978,7 +1006,7 @@ Handle<Value> Connection::ReceivedShutdown(const Arguments& args) {
|
||||
if (ss->ssl_ == NULL) return False();
|
||||
int r = SSL_get_shutdown(ss->ssl_);
|
||||
|
||||
if (r | SSL_RECEIVED_SHUTDOWN) return True();
|
||||
if (r & SSL_RECEIVED_SHUTDOWN) return True();
|
||||
|
||||
return False();
|
||||
}
|
||||
@@ -1485,7 +1513,7 @@ class Cipher : public ObjectWrap {
|
||||
|
||||
static Handle<Value> CipherInitIv(const Arguments& args) {
|
||||
Cipher *cipher = ObjectWrap::Unwrap<Cipher>(args.This());
|
||||
|
||||
|
||||
HandleScope scope;
|
||||
|
||||
cipher->incomplete_base64=NULL;
|
||||
@@ -1520,7 +1548,7 @@ class Cipher : public ObjectWrap {
|
||||
assert(iv_written == iv_len);
|
||||
|
||||
String::Utf8Value cipherType(args[0]->ToString());
|
||||
|
||||
|
||||
bool r = cipher->CipherInitIv(*cipherType, key_buf,key_len,iv_buf,iv_len);
|
||||
|
||||
delete [] key_buf;
|
||||
@@ -1658,6 +1686,19 @@ class Cipher : public ObjectWrap {
|
||||
outString = Encode(out_hexdigest, out_hex_len, BINARY);
|
||||
delete [] out_hexdigest;
|
||||
} else if (strcasecmp(*encoding, "base64") == 0) {
|
||||
// Check to see if we need to add in previous base64 overhang
|
||||
if (cipher->incomplete_base64!=NULL){
|
||||
unsigned char* complete_base64 = new unsigned char[out_len+cipher->incomplete_base64_len+1];
|
||||
memcpy(complete_base64, cipher->incomplete_base64, cipher->incomplete_base64_len);
|
||||
memcpy(&complete_base64[cipher->incomplete_base64_len], out_value, out_len);
|
||||
delete [] out_value;
|
||||
|
||||
delete [] cipher->incomplete_base64;
|
||||
cipher->incomplete_base64=NULL;
|
||||
|
||||
out_value=complete_base64;
|
||||
out_len += cipher->incomplete_base64_len;
|
||||
}
|
||||
base64(out_value, out_len, &out_hexdigest, &out_hex_len);
|
||||
outString = Encode(out_hexdigest, out_hex_len, BINARY);
|
||||
delete [] out_hexdigest;
|
||||
@@ -1677,8 +1718,10 @@ class Cipher : public ObjectWrap {
|
||||
initialised_ = false;
|
||||
}
|
||||
|
||||
~Cipher ()
|
||||
{
|
||||
~Cipher () {
|
||||
if (initialised_) {
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -1812,7 +1855,7 @@ class Decipher : public ObjectWrap {
|
||||
|
||||
static Handle<Value> DecipherInit(const Arguments& args) {
|
||||
Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This());
|
||||
|
||||
|
||||
HandleScope scope;
|
||||
|
||||
cipher->incomplete_utf8=NULL;
|
||||
@@ -1836,7 +1879,7 @@ class Decipher : public ObjectWrap {
|
||||
assert(key_written == key_len);
|
||||
|
||||
String::Utf8Value cipherType(args[0]->ToString());
|
||||
|
||||
|
||||
bool r = cipher->DecipherInit(*cipherType, key_buf,key_len);
|
||||
|
||||
delete [] key_buf;
|
||||
@@ -1850,7 +1893,7 @@ class Decipher : public ObjectWrap {
|
||||
|
||||
static Handle<Value> DecipherInitIv(const Arguments& args) {
|
||||
Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This());
|
||||
|
||||
|
||||
HandleScope scope;
|
||||
|
||||
cipher->incomplete_utf8=NULL;
|
||||
@@ -1886,7 +1929,7 @@ class Decipher : public ObjectWrap {
|
||||
assert(iv_written == iv_len);
|
||||
|
||||
String::Utf8Value cipherType(args[0]->ToString());
|
||||
|
||||
|
||||
bool r = cipher->DecipherInitIv(*cipherType, key_buf,key_len,iv_buf,iv_len);
|
||||
|
||||
delete [] key_buf;
|
||||
@@ -2087,6 +2130,7 @@ class Decipher : public ObjectWrap {
|
||||
int out_len;
|
||||
Local<Value> outString ;
|
||||
|
||||
out_value = NULL;
|
||||
int r = cipher->DecipherFinal(&out_value, &out_len, true);
|
||||
|
||||
if (out_len == 0 || r == 0) {
|
||||
@@ -2126,7 +2170,11 @@ class Decipher : public ObjectWrap {
|
||||
initialised_ = false;
|
||||
}
|
||||
|
||||
~Decipher () { }
|
||||
~Decipher () {
|
||||
if (initialised_) {
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -2247,7 +2295,7 @@ class Hmac : public ObjectWrap {
|
||||
}
|
||||
|
||||
int r;
|
||||
|
||||
|
||||
if( Buffer::HasInstance(args[0])) {
|
||||
Local<Object> buffer_obj = args[0]->ToObject();
|
||||
char *buffer_data = Buffer::Data(buffer_obj);
|
||||
@@ -2316,7 +2364,11 @@ class Hmac : public ObjectWrap {
|
||||
initialised_ = false;
|
||||
}
|
||||
|
||||
~Hmac () { }
|
||||
~Hmac () {
|
||||
if (initialised_) {
|
||||
HMAC_CTX_cleanup(&ctx);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -2472,7 +2524,11 @@ class Hash : public ObjectWrap {
|
||||
initialised_ = false;
|
||||
}
|
||||
|
||||
~Hash () { }
|
||||
~Hash () {
|
||||
if (initialised_) {
|
||||
EVP_MD_CTX_cleanup(&mdctx);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -2677,7 +2733,11 @@ class Sign : public ObjectWrap {
|
||||
initialised_ = false;
|
||||
}
|
||||
|
||||
~Sign () { }
|
||||
~Sign () {
|
||||
if (initialised_) {
|
||||
EVP_MD_CTX_cleanup(&mdctx);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -2726,29 +2786,54 @@ class Verify : public ObjectWrap {
|
||||
int VerifyFinal(char* key_pem, int key_pemLen, unsigned char* sig, int siglen) {
|
||||
if (!initialised_) return 0;
|
||||
|
||||
EVP_PKEY* pkey = NULL;
|
||||
BIO *bp = NULL;
|
||||
EVP_PKEY* pkey;
|
||||
X509 *x509;
|
||||
X509 *x509 = NULL;
|
||||
int r = 0;
|
||||
|
||||
bp = BIO_new(BIO_s_mem());
|
||||
if(!BIO_write(bp, key_pem, key_pemLen)) return 0;
|
||||
|
||||
x509 = PEM_read_bio_X509(bp, NULL, NULL, NULL );
|
||||
if (x509==NULL) return 0;
|
||||
|
||||
pkey=X509_get_pubkey(x509);
|
||||
if (pkey==NULL) return 0;
|
||||
|
||||
int r = EVP_VerifyFinal(&mdctx, sig, siglen, pkey);
|
||||
EVP_PKEY_free (pkey);
|
||||
|
||||
if (r != 1) {
|
||||
ERR_print_errors_fp (stderr);
|
||||
if (bp == NULL) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
return 0;
|
||||
}
|
||||
X509_free(x509);
|
||||
BIO_free(bp);
|
||||
if(!BIO_write(bp, key_pem, key_pemLen)) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check if this is a PKCS#8 public key before trying as X.509
|
||||
if (strncmp(key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0) {
|
||||
pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL);
|
||||
if (pkey == NULL) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
// X.509 fallback
|
||||
x509 = PEM_read_bio_X509(bp, NULL, NULL, NULL);
|
||||
if (x509 == NULL) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pkey = X509_get_pubkey(x509);
|
||||
if (pkey == NULL) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
r = EVP_VerifyFinal(&mdctx, sig, siglen, pkey);
|
||||
|
||||
if(pkey != NULL)
|
||||
EVP_PKEY_free (pkey);
|
||||
if (x509 != NULL)
|
||||
X509_free(x509);
|
||||
if (bp != NULL)
|
||||
BIO_free(bp);
|
||||
EVP_MD_CTX_cleanup(&mdctx);
|
||||
initialised_ = false;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -2893,7 +2978,11 @@ class Verify : public ObjectWrap {
|
||||
initialised_ = false;
|
||||
}
|
||||
|
||||
~Verify () { }
|
||||
~Verify () {
|
||||
if (initialised_) {
|
||||
EVP_MD_CTX_cleanup(&mdctx);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -2914,16 +3003,12 @@ void InitCrypto(Handle<Object> target) {
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
// Turn off compression. Saves memory - do it in userland.
|
||||
#ifdef SSL_COMP_get_compression_methods
|
||||
// Before OpenSSL 0.9.8 this was not possible.
|
||||
STACK_OF(SSL_COMP)* comp_methods = SSL_COMP_get_compression_methods();
|
||||
#if 0
|
||||
if (comp_methods && sk_SSL_COMP_num(comp_methods) > 0) {
|
||||
default_compression_method = sk_SSL_COMP_pop(comp_methods);
|
||||
fprintf(stderr, "SSL_COMP_get_name %s\n",
|
||||
SSL_COMP_get_name(default_compression_method->method));
|
||||
}
|
||||
#endif
|
||||
sk_SSL_COMP_zero(comp_methods);
|
||||
assert(sk_SSL_COMP_num(comp_methods) == 0);
|
||||
#endif
|
||||
|
||||
SecureContext::Initialize(target);
|
||||
Connection::Initialize(target);
|
||||
|
||||
@@ -596,7 +596,7 @@ static Handle<Value> SendFile(const Arguments& args) {
|
||||
ssize_t sent = eio_sendfile_sync (out_fd, in_fd, in_offset, length);
|
||||
// XXX is this the right errno to use?
|
||||
if (sent < 0) return ThrowException(ErrnoException(errno));
|
||||
return Integer::New(sent);
|
||||
return scope.Close(Integer::New(sent));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||