рдЗрддрдирд╛ рд╕рдордп рдкрд╣рд▓реЗ рдирд╣реАрдВ, рдЕрд░реНрдерд╛рддреН 2011-10-05 рдХрдиреЗрдХреНрдЯ 2.0 рдлреНрд░реЗрдорд╡рд░реНрдХ рдХрд╛ рдПрдХ рдирдпрд╛ рд╕рдВрд╕реНрдХрд░рдг рдЬрд╛рд░реА рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рд╣рдм рдкрд░ рдПрдХ рдЕрдВрддрд░ рджреЗрдЦрд╛ рдЧрдпрд╛, рдФрд░ рдлрд┐рд░ рдХреБрдЫ рдШрдВрдЯреЛрдВ рдХреЗ рд▓рд┐рдП рдмрд╛рд╣рд░ рдЖрдпрд╛ред рдореИрдВ 29 рдлрд░рд╡рд░реА рдХреЛ рдЬрд╛рд░реА рдХрд┐рдП рдЧрдП рд╕рдВрд╕реНрдХрд░рдг 2.0.1 рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рддреБрд░рдВрдд рд▓рд┐рдЦреВрдВрдЧрд╛ред рджреВрд╕рд░реЗ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдмрд╣реБрдд рдЖрд╡рд╢реНрдпрдХ рдФрд░ рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рдкреНрд░рддреАрдХреНрд╖рд┐рдд рдкрд░рд┐рд╡рд░реНрддрди рдХрд┐рдП рдЧрдП рдереЗред
рдПрдХ рд╕рд░реНрд╡рд░ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХреЗ рд▓рд┐рдП HTTP рдФрд░ HTTPS!
Connect.Server рдХреЛ рдкрд╣рд▓реЗ NodeJS рдХреЛрд░ рд╕реЗ net.Server рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рдерд╛, рдЬрд┐рд╕рд╕реЗ HTTP рдФрд░ HTTPS рджреЛрдиреЛрдВ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдиреЗ рдореЗрдВ рдЕрд╕реБрд╡рд┐рдзрд╛ рд╣реБрдИред рдирддреАрдЬрддрди, рдХрдиреЗрдХреНрдЯ () (рдкрд╣рд▓реЗ рд╕реЗ рдХрдиреЗрдХреНрдЯред рдХреНрд░реЗрдЯрд╕реЗрд╡рд░ ()) рдПрдХ рдирдпрд╛ рдлрд╝рдВрдХреНрд╢рди рдЕрдзрд┐рдХ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рдмрди рдЧрдпрд╛ рд╣реИред рдЗрд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдЖрдк рдХреЙрд▓ рдХреЛ app.listen () рдкрд░ рдЫреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдиреЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, NodeJS рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ:
var connect = require('connect'), http = require('http'), https = require('https'); tlsOptions = { key: fs.readFileSync('keys/key.pem'), cert: fs.readFileSync('keys/cert.pem') }; var app = connect() .use(function(req, res) { res.end('hello habrahabr\n'); }) http.createServer(app).listen(80); https.createServer(tlsOptions, app).listen(443);
рдмреЗрд╣рддрд░ рдХреНрд╡реЗрд░реА рдкрд╛рд░реНрд╕рд░
BodyParser () рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рдЖрд╡рдХ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирдП рдХрд╛рд░реНрдп рдЬреЛрдбрд╝реЗ рдЧрдП рд╣реИрдВ: рдЖрд╡реЗрджрди / json рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд▓рд┐рдП json (), рдорд▓реНрдЯреАрдкрд╛рд░реНрдЯ / рдлреЙрд░реНрдо-рдбреЗрдЯрд╛ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд▓рд┐рдП рдорд▓реНрдЯреАрдкрд╛рд░реНрдЯ () рдФрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди / x-www-form-urlencoded рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд▓рд┐рдП urlencoded ()ред рд╕рднреА req.body рдХреЗ рд▓рд┐рдП рдкреНрд░рд╢реНрдиреЛрдВ рдореЗрдВ рдкреНрд░реЗрд╖рд┐рдд рдбреЗрдЯрд╛ рддрдХ рдкрд╣реБрдБрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдирдП рдЕрд╡рд╕рд░реЛрдВ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдорд▓реНрдЯреАрдкрд╛рд░реНрдЯ () рдлрд╝рдВрдХреНрд╢рди рди рдХреЗрд╡рд▓ req.body рдореЗрдВ рдкреНрд░реЗрд╖рд┐рдд рдорд╛рдкрджрдВрдбреЛрдВ рддрдХ рдкрд╣реБрдВрдЪ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рдбрд╛рдЙрдирд▓реЛрдб рдХреА рдЧрдИ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП рднреА req.filesред
рдЖрдк рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдкреЗрд╕рд░реНрд╕ рдХреЛ рдХрдиреЗрдХреНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
app.use(connect.json()); app.use(connect.urlencoded()); app.use(connect.multipart());
рдпрд╣ рд▓рд┐рдЦрдиреЗ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реЛрдЧрд╛:
app.use(connect.bodyParser());
рдХрд░реНрдиреЗрд▓-рд╕реНрддрд░ рдЕрдкрд╕реНрдлреАрддрд┐ рдФрд░ рдЧрдЬрд╝рд┐рдк рд╕рдорд░реНрдерди
рдиреЛрдб рд╕рдВрд╕реНрдХрд░рдг 0.6.0 рдХреЗ рдмрд╛рдж рд╕реЗ, рд╕рдВрдкреАрдбрд╝рди (zlib.createGzip рдФрд░ zlib.createDeflate) рдХрд╛ рдореВрд▓ рдЙрдкрдпреЛрдЧ рдЙрдкрд▓рдмреНрдз рд╣реЛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдиреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЗрдХ () рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рд╣реИред рдРрдб-рдСрди рдореЗрдВ рджреЗрд╢реА рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП
рд╕рдВрдкреАрдбрд╝рди рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рд╣реИрдВ ред
рдХреБрдХреА рдкрд╛рд░реНрд╕рд░
рдХреБрдХреАрдкрд╛рд░реНрд╕рд░ () рдХреЗ рдкреВрд░рдХ рдХреЗ рд▓рд┐рдП рдЕрдм рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдЙрдкрд▓рдмреНрдз рд╣реИрдВред рдкрд╣рд▓реЗ, рдЖрдкрдХреЛ рд╕рддреНрд░ ({рдЧреБрдкреНрдд: рд╕реНрдЯреНрд░рд┐рдВрдЧ}) рдФрд░ рд╕рддреНрд░ () рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдерд╛ред рдЕрдм рдЖрдк req.signedCookies рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рдХреБрдХреАрдЬрд╝ рдФрд░ рдЕрдкрдиреЗ рд╕рддреНрд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд╕рд╛рде рд╣реА req.cookies рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЕрд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рдХреБрдХреАрдЬрд╝ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
connect() .use(connect.cookieParser('keyboard cat')) .use(function(req, res, next){ res.end(JSON.stringify(req.cookies)); })
рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдореЗрдВ рддреНрд░реБрдЯрд┐
рдкрд╣рд▓реЗ, рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдПрдХ рд╕рдорд╕реНрдпрд╛ рдереАред рд╕рднреА рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рддреНрд░реБрдЯрд┐рд╣реИрдВрдбрд▓рд░ () рдХрдиреЗрдХреНрдЯ () рдореЗрдВ рд╣реА рдкрдХрдбрд╝рд╛ рдЧрдпрд╛ рдФрд░ рдорд╛рдирдХ рдкреГрд╖реНрда рдЬрд╛рд░реА рдХрд┐рдП рдЧрдПред рдЕрдм рдЖрдк рдЕрдкрдиреЗ рдХреЛрдб рдореЗрдВ рдЕрдЧрд▓реЗ (рдЧрд▓рдд) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
app.use(function(err, req, res, next){ if (4 == err.status / 100) {
рдЕрдзрд┐рд╡реЗрд╢рди
рдЬреИрд╕рд╛ рдХрд┐ рдкрд╣рд▓реЗ рд╣реА рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд╕рддреНрд░ () рдореЗрдВ рдЕрдм рдЧреБрдкреНрдд рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдХреБрдХреАрдЬрд╝ рдХреЗ рд▓рд┐рдП, .maxAge рдЧреБрдг рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╢реВрдиреНрдп рдерд╛, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рдерд╛ рдХрд┐ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдмрдВрдж рд╣реЛрдиреЗ рдкрд░ рд╕рднреА рдХреБрдХреАрдЬрд╝ рд╕реЗрдЯ рд╣рдЯрд╛ рджрд┐рдП рдЧрдП рдереЗред
рд╕рд╛рдЗрдб рдЬреЛрдбрд╝
рдХрдиреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА рдРрдб-рдСрди рдЪрд╛рд▓реВ рд░рд╣рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рдПрдХреНрд╕рдкреНрд░реЗрд╕ 2.0 рдХреЗ рд╕рд╛рде рдЕрд╕рдВрдЧрдд рд╣реИ, рдПрдХреНрд╕рдкреНрд░реЗрд╕ 3.0 рд╕реЗ рдмрд╛рд╣рд░ рдЖрдиреЗ рдХреА рдЙрдореНрдореАрдж рд╣реИ!
рд╕рднреА рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреА рд╕реВрдЪреА
рд╡рд░реНрдгрд┐рдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрджрд▓рд╛рд╡ рдХрд┐рдП рдЧрдП рдереЗ, рд╕рд╛рде рд╣реА рдХрдИ рдЕрдиреНрдп рдЬреЛ рдПрдкреАрдЖрдИ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рдореЛрдЪрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рднреА рдкрд░реАрдХреНрд╖рдг рдХрд┐рдП рдЧрдП рдереЗред
2.0.1 / 2012-02-29- Vhost () рдРрдб-рдСрди рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рдХрд╡рд░реЗрдЬ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛
- SHA-2 [senotrusov] рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдХреА рд╕рдорд░реНрдерди рдХреЗ рд▓рд┐рдП рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХреБрдХреАрдкреНрд░реЗрдЬрд╝рд░ () рд╣рд╕реНрддрд╛рдХреНрд╖рд░
- рд╕реНрдерд┐рд░ рд╕реНрдерд┐рд░ () рд░реЗрдВрдЬ: 416 рдХреЗ рд╕рд╛рде рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЕрдЧрд░ рдЕрд╕рдВрднрд╡ рд╣реИ
- рдирд┐рд╢реНрдЪрд┐рдд vhost () рдЬреЛрдбрд╝ред # 494 рдмрдВрдж рдХрд░реЗрдВ
2.0.0 / 2011-10-05- рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдХреБрдХреА () рдХреБрдХреА рдХреЗрд╡рд▓ рдРрдб-рдСрди
- рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рд╕реЗрдХ () рдРрдб-рдСрди рдЧрдЬрд╝рд┐рдк / рдбрд┐рдлреНрд▓реЗрдЯ рд╕рдкреЛрд░реНрдЯ рдХреЗ рд▓рд┐рдП
- рдПрдХреНрд╕-рдлрд╝реЙрд░реНрд╡рд░реНрдб-рдкреНрд░реЛрдЯреЛ рдХреА рдЬрд╛рдБрдЪ рдХреЗ рд▓рд┐рдП рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рд╕рддреНрд░ () "рдкреНрд░реЙрдХреНрд╕реА" рд╕реЗрдЯрд┐рдВрдЧ
- рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдЬреЛрдВрд╕ () рдРрдб-рдСрди рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП "рдЖрд╡реЗрджрди / json"
- рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ urlencoded () рдРрдб-рдСрди рдХреЛ "рдПрдкреНрд▓рд┐рдХреЗрд╢рди / x-www-form-urlencoded" рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
- "рдорд▓реНрдЯреАрдкрд╛рд░реНрдЯ / рдлреЙрд░реНрдо-рдбреЗрдЯрд╛" рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдорд▓реНрдЯреАрдЖрд░реНрдЯ () рдРрдб-рдСрди
- рд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рдХреБрдХреАрдЬрд╝ рдХреЗ рд▓рд┐рдП рдХреБрдХреАрдкрд╛рд░реНрд╕рд░ (рдЧреБрдкреНрдд) рдХрд╛ рдЙрдкрдпреЛрдЧ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛
- рдХреБрдХреА рдХреБрдХреА () рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдХреБрдХреА рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рд╕рдорд░реНрдерди
- рдХреБрдХреАрдЬрд░реНрд╕ рдореЗрдВ рдХреБрдХреАрдЬрд╝ рдХреЗ JSON рдХреНрд░рдорд╛рдВрдХрди рдХреЗ рд▓рд┐рдП рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рд╕рдорд░реНрдерди ()
- рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдХрдиреЗрдХреНрдЯ рдореЗрдВ рдЗрд░реЗрдЯрд╛рд╕реНрдЯрд╕ рд╕рдорд░реНрдерди рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛
- рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ X-Cache MISS / HIT to staticCache ()
- рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ res.headerSent рдиреЛрдб рдиреЛрдбреНрд╕ res._headerSent рдЬрд╛рдБрдЪ рд░рд╣рд╛ рд╣реИ рдЬрдм рддрдХ рдиреЛрдб рдХрд░рддрд╛ рд╣реИ
- рдмреЗрд╕рд┐рдХ рдСрдереЗрдВрдЯ () req.remoteUser рдХреЛ req.user рдореЗрдВ рдмрджрд▓рд╛ рдЧрдпрд╛
- рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╕рддреНрд░ рдХреБрдХреА рдореЗрдВ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╕рддреНрд░ () рдмрджрд▓ рдЧрдпрд╛ рд╣реИред # 475 рдмрдВрдж рдХрд░рддрд╛ рд╣реИ
- рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдирд╣реАрдВ рдЕрдм рд▓реЛрдЕрд░рдХреЗрд╕ рдХреБрдХреА рдирд╛рдо
- рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдмреЙрдбреАрдкреИрд░ () рдЕрдм json (), urlencoded () рдФрд░ рдорд▓реНрдЯреАрдкрд╛рд░реНрдЯ () рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ
- ErrorHandler () рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдУрд╡рд░рд░рд╛рдЗрдб рд╡рд┐рдХрд▓реНрдк (рд╡рд┐рдХрд╛рд╕ рдореЗрдВ)
- рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдЧрд▓реЗ () рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЛ рдмрджрд▓рдиреЗ рд╕реЗ рдЖрдЧреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рд╡рд┐рдХрд▓реНрдк рдорд┐рд▓рддреЗ рд╣реИрдВ
- рдПрдХ рдЖрд╡реЗрджрди рдореЗрдВ http рдФрд░ https рдмрдирд╛рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХреЗ рд▓рд┐рдП http [s] рд╣рдЯрд╛рдПрдВ
- рд╣рдЯрд╛рдП рдЧрдП .createServer () (рдХрдиреЗрдХреНрдЯ рдХрдиреЗрдХреНрдЯ) ()
- рд╕рддреНрд░ рдореЗрдВ рд╣рдЯрд╛ рджреА рдЧрдИ рдЧреБрдкреНрдд рд╕рдВрдкрддреНрддрд┐ (), рдХреБрдХреАрдкреНрд░реЗрдЬрд░ (рдЧреБрдкреНрдд) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ
- рд╣рдЯрд╛рдП рдЧрдП Connect.session.ignore рд╕рд░рдгреА рд╕рдорд░реНрдерди
- рд╣рдЯрд╛рдП рдЧрдП рд░рд╛рдЙрдЯрд░ () рдПрдб-рдСрдиред # 262 рдмрдВрдж рдХрд░рддрд╛ рд╣реИ
- рдлрд┐рдХреНрд╕реНрдб рд╕реЗрдЯ-рдХреБрдХреА рдкреНрд░рддрд┐ рд╕рддреНрд░ рдХреЗрд╡рд▓ 1 рдмрд╛рд░
- рдлрд┐рдХреНрд╕реНрдб FQDN рд╕рдорд░реНрдердиред "/" рдирд╣реАрдВ рдЬреЛрдбрд╝рддрд╛
- XSS рдХреЗ рджреМрд░рд╛рди рдлрд┐рдХреНрд╕реНрдб 404ред # 473 рдмрдВрдж рдХрд░рддрд╛ рд╣реИ
- 404 рдФрд░ 500 рдЬреЗрдирд░реЗрдЯ рдХрд┐рдП рдЧрдП рдХрдиреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рдлрд┐рдХреНрд╕реНрдб HEAD рд╕рдкреЛрд░реНрдЯ
рдЕрдм рд╣рдо рдПрдХреНрд╕рдкреНрд░реЗрд╕ 3 рдХрд╛ рдЗрдВрддрдЬрд╛рд░ рдХрд░ рд░рд╣реЗ рд╣реИрдВ!
рд╕реНрд░реЛрдд рдФрд░ рд▓рд┐рдВрдХ:
TJ Holowaychuk рдмреНрд▓реЙрдЧ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдХрдиреЗрдХреНрдЯ рдкреГрд╖реНрдардЬреАрдердм рдХрдиреЗрдХреНрдЯ