рдмрд╣реБрдд рдкрд╣рд▓реЗ рдирд╣реАрдВ, рдореИрдВрдиреЗ рдХреЙрдорди рд▓рд┐рд╕реНрдк рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛ред рдРрд╕рд╛ рд▓рдЧ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдПрдХ рдирдИ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рд╕реАрдЦрдирд╛ рдХреЛрдИ рдЖрд╕рд╛рди рдХрд╛рдо рдирд╣реАрдВ рд╣реИ, рдЦрд╛рд╕рдХрд░ рдЕрдЧрд░ рдпрд╣ рдЙрди рд╕рднреА рднрд╛рд╖рд╛рдУрдВ рд╕реЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рд╣реИ рдЬреЛ рдЖрдкрдиреЗ рдкрд╣рд▓реЗ рд╕рд╛рдордирд╛ рдХреА рд╣реИрдВред рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ
рд▓реИрдВрдб рдСрдл рд▓рд┐рд╕реНрдк рдХреЗ рд╕рд╛рде рд╢реБрд░реБрдЖрдд рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рдХрд┐рддрд╛рдм рдмрд╣реБрдд рдЕрдЪреНрдЫреА рд╣реИ, рджрд┐рд▓рдЪрд╕реНрдк рддрд╕реНрд╡реАрд░реЛрдВ рдХреЗ рд╕рд╛рде рдФрд░ рд╢реБрд░реБрдЖрддреА рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдЪреНрдЫреА рд╣реИред рдПрдХ рдЕрдзреНрдпрд╛рдп рдореЗрдВ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдХреЙрдорди рд▓рд┐рд╕реНрдк рдкрд░ рдПрдХ рд╡реЗрдм рд╕рд░реНрд╡рд░ рдХреИрд╕реЗ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдореИрдВрдиреЗ рдЗрд╕ рд╡рд┐рд╖рдп рдХреЛ рдереЛрдбрд╝рд╛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛, рдФрд░ рдЕрдВрдд рдореЗрдВ рдореБрдЭреЗ рдЗрд╕ рдЕрдзреНрдпрд╛рдп рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдирд╣реАрдВ рдорд┐рд▓рд╛, рд▓реЗрдХрд┐рди рдПрдХ рдмрд╣реБрдд рд╣реА рджрд┐рд▓рдЪрд╕реНрдк рд╡реЗрдм рд╕рд░реНрд╡рд░ рдерд╛ред рд╕реНрд░реЛрдд рдХреЛрдб
рдпрд╣рд╛рдВ рджреЗрдЦреЗ рдЬрд╛ рд╕рдХрддреЗ
рд╣реИрдВ ред
рдЗрд╕реЗ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ emacs, sbcl, slime рдФрд░ quicklisp рдХреЗ рд╕рд╛рде рд▓рд┐рдирдХреНрд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдореБрдЭреЗ рдпрд╣ рд╡рд░реНрдгрди рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдЗрд╕реЗ рдХреИрд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдП, рдЗрд╕реЗ рдХреИрд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЬрд╛рдП рдФрд░ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рдП - рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдЗрдВрдЯрд░рдиреЗрдЯ рдкрд░ рдХрдИ рд▓реЗрдЦ рд╣реИрдВред рд╣рдорд╛рд░рд╛ рдкреВрд░рд╛ рд╡реЗрдм рд╕рд░реНрд╡рд░ рдПрдХ рдкреИрдХреЗрдЬ рдореЗрдВ рд╣реЛрдЧрд╛ рдЬрд┐рд╕реЗ myweb рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рдирд╛рдо рд╕реЗ рдПрдХ рдлрд╝реЛрд▓реНрдбрд░ рдмрдирд╛рдПрдБ, рдФрд░ рдЗрд╕рдореЗрдВ рджреЛ рдлрд╝реЛрд▓реНрдбрд░ рд▓реЙрдЧ рдФрд░ рд╡реЗрдм рдмрдирд╛рдПрдБред рд▓реЙрдЧ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рд╡реЗрдм рд╕рд░реНрд╡рд░ рд▓реЙрдЧ рдлрд╝рд╛рдЗрд▓ рд╣реЛрдЧреАред рд╡реЗрдм рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ html- рдкреГрд╖реНрда рдФрд░ рдЪрд┐рддреНрд░ рд╣реЛрдВрдЧреЗ рдЬреЛ рд╡реЗрдм рд╕рд░реНрд╡рд░ рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЛ рджреЗрдЧрд╛ред рдкреВрд░реЗ рд╡реЗрдм рд╕рд░реНрд╡рд░ рдореЗрдВ рд╕рд╛рдд рдлрд╛рдЗрд▓реЗрдВ рд╣реЛрддреА рд╣реИрдВред
рдЖрдЗрдП рдкреИрдХреЗрдЬ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рдиреЗ рд╡рд╛рд▓реА рдлрд╛рдЗрд▓ рдФрд░ рдкреИрдХреЗрдЬ рд╡рд┐рд╡рд░рдг рдХреЗ рд▓рд┐рдП asd рдлрд╛рдЗрд▓ рд╢реБрд░реВ рдХрд░реЗрдВред
Package.lisp рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдБ:
(in-package :cl-user) (defpackage :myweb (:use :cl :usocket :bordeaux-threads) (:export :start-http :stop-http :list-workers :list-requests)) (defpackage :myweb.util (:use :cl :local-time) (:export :parse-request :read-utf-8-string :response-write :get-param :get-header :http-response :file-response :html-template :log-info :log-warning :log-error)) (defpackage :myweb.handler (:use :cl) (:export :process-request))
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╣рдорд╛рд░реЗ рд╡реЗрдм рд╕рд░реНрд╡рд░ рдореЗрдВ рддреАрди рдкреИрдХреЗрдЬ рд╣реИрдВ:
- myweb - рд╡реЗрдм рд╕рд░реНрд╡рд░ рдХреЛ рд╢реБрд░реВ рдХрд░рдиреЗ рдФрд░ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдп рдХрд░реЗрдЧрд╛
- myweb.util - рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдп рд╢рд╛рдорд┐рд▓ рд╣реЛрдВрдЧреЗ
- myweb.handler - рдореЗрдВ рд╕реНрд╡рдпрдВ рд╣реА рдЕрдиреБрд░реЛрдз рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЛрдб рд╣реЛрдЧрд╛
рдЗрди-рдкреИрдХреЗрдЬ рдлрд╝рдВрдХреНрд╢рди рдЖрдорддреМрд░ рдкрд░ рдлрд╝рд╛рдЗрд▓ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЙрд╕ рдкреИрдХреЗрдЬ рдХреЗ рдирд╛рдо рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╣рдо рдЪрд░ рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдШреЛрд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЪреВрдВрдХрд┐ рд╣рдо рдкреИрдХреЗрдЬреЛрдВ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рдореБрдЦреНрдп рдкреИрдХреЗрдЬ: cl-user рдореЗрдВ рдШреЛрд╖рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдиреЛрдЯ
: рдкреИрдХреЗрдЬ рдШреЛрд╖рдгрд╛рдУрдВ рдореЗрдВ
рдЙрдкрдпреЛрдЧ рдФрд░
рдирд┐рд░реНрдпрд╛рдд рдирд┐рд░реНрджреЗрд╢ред
: рдЙрдкрдпреЛрдЧ рд╣рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рдирд╛рдо рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдкреИрдХреЗрдЬ рдХреЗ рдирд╛рдо рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдП рдмрд┐рдирд╛ рдЕрдиреНрдп рдкреИрдХреЗрдЬреЛрдВ рд╕реЗ рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдЯрд╛рдЗрдк рдХрд┐рдП рдЧрдП рдкрд╛рда рдХреА рдорд╛рддреНрд░рд╛ рдХрдо рд╣реЛ рдЬрд╛рддреА рд╣реИред
: рдирд┐рд░реНрдпрд╛рдд рдЙрди рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдирд╛рдо рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рдирдХрд╛ рдЙрдкрдпреЛрдЧ рдкреИрдХреЗрдЬ рдХреЗ рдмрд╛рд╣рд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкреИрдХреЗрдЬ рд╣реИ: myweb рдлрд╝рдВрдХреНрд╢рдВрд╕: рд╕реНрдЯрд╛рд░реНрдЯ-http рдФрд░: рд╕реНрдЯреЙрдк-httpред рдкреИрдХреЗрдЬ рдореЗрдВ рд╣реЛрдиреЗ рдХреЗ рдХрд╛рд░рдг: cl-user, рд╣рдо рдЙрдиреНрд╣реЗрдВ myweb: start-http рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреЙрд▓ рдирд╣реАрдВ рдХрд░ рдкрд╛рдПрдВрдЧреЗ, рдЬрдм рддрдХ рдХрд┐ рд╣рдо рдкрд╣рд▓реА рдмрд╛рд░ рдЙрдиреНрд╣реЗрдВ: рдирд┐рд░реНрдпрд╛рдд рдирд┐рд░реНрджреЗрд╢ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдШреЛрд╖рд┐рдд рдирд╣реАрдВ рдХрд░рддреЗред
рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреИрдХреЗрдЬреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдЬреНрдЮрд╛рдкрди рд╣реИ, рдЕрдм рдЗрди рдкреИрдХреЗрдЬреЛрдВ рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЛ рд▓рд┐рдЦрдирд╛ рдмрд╛рдХреА рд╣реИред Web.lisp, use.lisp рдФрд░ handler.lisp рдлрд╛рдЗрд▓реЗрдВ рдмрдирд╛рдПрдВ рдФрд░ рдЙрдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдореЗрдВ рдПрдХ рдЗрди-рдкреИрдХреЗрдЬ рдХреЙрд▓ рдЬреЛрдбрд╝реЗрдВред Web.lisp рдХреЗ рд▓рд┐рдП - (рдЗрди-рдкреИрдХреЗрдЬ: myweb), use.lisp (рдЗрди-рдкреИрдХреЗрдЬ: myweb.util), рдЖрджрд┐ рдХреЗ рд▓рд┐рдПред рд╣рдореЗрдВ рдХреЙрд▓ (рдЗрди-рдкреИрдХреЗрдЬ: рдХреНрд▓-рд▓реЙрдЧ) рдХреЗ рд╕рд╛рде рдПрдХ log.lisp рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдиреЗ рдХреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдЗрд╕ рдлрд╛рдЗрд▓ рдХреЛ
рдХреНрд▓реИрдЯ-рд▓реЙрдЧ рд▓реЙрдЧрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдХреЛ рдЪрд▓рд╛рдиреЗ рдФрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИред
рд╡реЗрдм рд╕рд░реНрд╡рд░ рдХреЗ рд▓рд┐рдП рдлрд╝рд╛рдЗрд▓ рд╕рдВрд░рдЪрдирд╛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдВрддрд┐рдо рд╕реНрдкрд░реНрд╢ myweb.asd рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рд╣реЛрдЧрд╛, рдЬреЛ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА рдЪреАрдЬреЛрдВ рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП asdf рд╕рд┐рд╕реНрдЯрдо рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
рдХреБрдВрдЬреА: рд╕реАрд░рд┐рдпрд▓ рдЯреА рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ asdf рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЙрд╕реА рдХреНрд░рдо рдореЗрдВ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╡реЗ рд╕реВрдЪреАрдмрджреНрдз рд╣реИрдВред
рдЕрдм рд╣рдореЗрдВ рдлрд╝рд╛рдЗрд▓ load.lisp рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛, рдЬреЛ рд╣рдорд╛рд░реЗ рдкреИрдХреЗрдЬ рдХреЛ рд▓реЛрдб рдХрд░реЗрдЧрд╛ рдФрд░ рдХреАрдЪрдбрд╝ рдХреЗ рд▓рд┐рдП рд╣рдВрд╕ рд╕рд░реНрд╡рд░ рд╢реБрд░реВ рдХрд░реЗрдЧрд╛ред
(in-package :cl-user) (quicklisp:quickload "swank") (quicklisp:quickload "usocket") (quicklisp:quickload "bordeaux-threads") (quicklisp:quickload "trivial-utf-8") (quicklisp:quickload "cl-log") (quicklisp:quickload "local-time") (pushnew '*default-pathname-defaults* asdf:*central-registry*) (asdf:load-system 'myweb) (swank:create-server)
рд╡рд┐рдХрд╛рд╕ рдЬрд╛рд░реА рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕реНрд╡рд┐рдВрдХ рдХреЛ рдЪрд▓рд╛рдиреЗ рдФрд░ рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЛ рдХреНрд╡рд┐рдХрд▓рд╛рдЗрдЬрд╝ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓реЛрдб рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдорд╛рдпрд╡реЗрдм рдбрд╛рдпрд░реЗрдХреНрдЯрд░реА рдореЗрдВ sbcl рдЪрд▓рд╛рдПрдВ рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВ (Quicklisp: quickload "swank")ред Swank рдХреЛ рдЗрдирд╕реНрдЯреЙрд▓ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж sbcl рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рд╕реЗ swank рд╕рд░реНрд╡рд░ рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ (swank: create-server) рд╢реБрд░реВ рдХрд░реЗрдВред
Emacs рд╕реЗ рдХреАрдЪрдбрд╝-рдХрдиреЗрдХреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛, sbcl рдЪрд▓рд╛рдиреЗ рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░рдирд╛ рдФрд░ load.lisp рд╕реЗ рдЕрдиреНрдп рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рдХреЛ quickacisp рдХреЗ рд╕рд╛рде рдХреЙрд▓ рдХрд░рдирд╛ред emacs рдореЗрдВ slime-mode рдФрд░ ctrl-e рдХреБрдВрдЬреА рд╕рдВрдпреЛрдЬрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ред рдпрджрд┐ рдЖрдкрдиреЗ рд╕рдм рдХреБрдЫ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рдХреНрд╡рд┐рдХрдкреНрд▓рд╕ рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЛ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реЗрдЧрд╛ рдФрд░ рдЖрдкрдХреЗ рд▓рд┐рдП asdf рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЙрдиреНрд╣реЗрдВ рд▓реЛрдб рдХрд░реЗрдЧрд╛ред рд╕рдм рдХреБрдЫ рд╡рд┐рдХрд╛рд╕ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИред
рд╡реЗрдм рд╕рд░реНрд╡рд░ рд╕реЗ рд╣реА рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рдЙрд╕рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рдХреБрд░реНрд╕рд┐рдпрд╛рдВ тАЛтАЛрдЪрд╛рд╣рд┐рдПред рдореИрдВрдиреЗ рд╡реНрдпрд╛рдкрдХ
usocket рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реЙрдХреЗрдЯреНрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рд╣рдореЗрдВ рдереНрд░реЗрдбреНрд╕ рдХреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рд╣рдо
рдмреЛрд░реНрдбреЛ-рдереНрд░реЗрдбреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред рд▓реЗрдХрд┐рди рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВ http- рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рдореЙрдбрд▓ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдЬреЛ рд╣рдо рдмрдирд╛рдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВред рдкреНрд░рддреНрдпреЗрдХ рдЕрдиреБрд░реЛрдз рдХреЛ рдПрдХ рдЕрд▓рдЧ рдереНрд░реЗрдб рджреНрд╡рд╛рд░рд╛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдзрд╛рдЧреЗ рд╣реЛрдВрдЧреЗ рдЬреЛ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдмрдирд╛рдП рдЬрд╛рдПрдВрдЧреЗред рдЙрдирдореЗрдВ рд╕реЗ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдирд┐рд╖реНрдХреНрд░рд┐рдп рдзрд╛рд░рд╛рдПрдБ рд╣реЛрдВрдЧреА, рдЬреЛ рдЕрдиреБрд░реЛрдз рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдирдП рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд▓рд┐рдП, рдкреНрд░рддреАрдХреНрд╖рд╛-рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдЪрд▓реА рдЬрд╛рдПрдВрдЧреАред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЖрдк рдирдП рд╡рд░реНрдХрд░ рдереНрд░реЗрдб рдмрдирд╛рдиреЗ рдХрд╛ рдмреЛрдЭ рдХрдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ http рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдереНрд░реЗрдб рдкреВрд▓ рддрдВрддреНрд░ рдирд┐рдХрд▓рд╛ рд╣реИред
рдЪрд▓рд┐рдП web.lisp рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдореНрдпреВрдЯреЗрдХреНрд╕ s рдХреЗ рд▓рд┐рдП рд╕реЙрдХреЗрдЯ рдФрд░ рдЪрд░ рдШреЛрд╖рд┐рдд рдХрд░рдХреЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ:
(defvar *listen-socket* nil) (defvar *listen-thread* nil) (defvar *request-mutex* (make-lock "request-mutex")) (defvar *request-threads* (list)) (defvar *worker-mutex* (make-lock "worker-mutex")) (defvar *workers* (list)) (defvar *worker-num* 0) (defvar *idle-workers* (list)) (defvar *idle-workers-num* 0) (defvar *request-queue* (list))
рдереНрд░реЗрдбреНрд╕ рдореЗрдВ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдФрд░ рд╡рд┐рддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рдЕрд▓рдЧ рдереНрд░реЗрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ, рдЬреЛ рдкреЙрдЗрдВрдЯрд░ рдХреЛ * рд╕реБрдиреЛ-рдереНрд░реЗрдб * рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЪрд▓рд┐рдП рд╕реНрдЯрд╛рд░реНрдЯ-http рд╡рд┐рдзрд┐ рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ:
(defun start-http (host port &key (worker-limit 10) (idle-workers 1)) (if (not *listen-socket*) (setq *listen-thread* (make-thread (lambda () (http-acceptor host port worker-limit idle-workers)) :name "socket-acceptor")) "http server already started"))
рдпрд╣ рдбрд┐рд╕реНрдкреЗрдВрд╕рд░ рд╕реНрдЯреНрд░реАрдо рдХреЛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд░рд▓ рдлрд╝рдВрдХреНрд╢рди рд╣реИ, рдЬреЛ рдмрджрд▓реЗ рдореЗрдВ http-acceptor рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░реЗрдЧрд╛ред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рджреЛ рдЪрд╛рдмрд┐рдпрд╛рдБ рд╣реИрдВ - рдпрд╣ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛-рд╕реАрдорд╛ рд╣реИ - рд╢реНрд░рдорд┐рдХреЛрдВ рдХреА рдЕрдзрд┐рдХрддрдо рд╕рдВрдЦреНрдпрд╛, рдФрд░ рдирд┐рд╖реНрдХреНрд░рд┐рдп-рд╢реНрд░рдорд┐рдХ - рдирд┐рд╖реНрдХреНрд░рд┐рдп рд╢реНрд░рдорд┐рдХреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ред
рдЪрд▓рд┐рдП рдХреНрд╡реЗрд░реА рд╡рд┐рддрд░рдг рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╕реНрд╡рдпрдВ рд▓рд┐рдЦрддреЗ рд╣реИрдВ:
(defun http-acceptor (host port worker-limit idle-workers) (setq *listen-socket* (socket-listen host port :reuse-address t :element-type '(unsigned-byte 8) :backlog (* worker-limit 2))) (let ((request-id 0) (worker-id 0)) (loop while *listen-thread* do (let* ((socket (socket-accept *listen-socket* :element-type '(unsigned-byte 8)))) (progn (setq request-id (1+ request-id)) (acquire-lock *worker-mutex*) (if (>= *worker-num* worker-limit) (push (cons request-id socket) *request-queue*)
рдкрд╣рд▓реА рдЪреАрдЬрд╝ рдЬреЛ рд╣рдо рдХрд░рддреЗ рд╣реИрдВ рд╡рд╣ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдкрддреЗ рдФрд░ рдкреЛрд░реНрдЯ рдХреЛ рд╕реЙрдХреЗрдЯ-рд╕реБрдирдирд╛ рд╣реИред рд▓реВрдк рдореЗрдВ рдЖрдЧреЗ, рд╣рдо рд╕реЙрдХреЗрдЯ-рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдЬреБрдбрд╝реЗ рдХреНрд▓рд╛рдЗрдВрдЯ рдкрд░ рд╕реЙрдХреЗрдЯ рд╣реЛрддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рд╣рдореЗрдВ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдореЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд╕рд╛рде рд╣реА рд╣рдо рд░рд┐рдХреНрд╡реЗрд╕реНрдЯ рдореЗрдВ рд░рд┐рдХреНрд╡реЗрд╕реНрдЯ-рдЖрдИрдбреА рдЕрд╕рд╛рдЗрди рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕ рд╕реНрддрд░ рдкрд░, рд╣рдореЗрдВ рдпрд╣ рддрдп рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдЕрдиреБрд░реЛрдз рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдХреИрд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдирд┐рд╖реНрдХреНрд░рд┐рдп рдереНрд░реЗрдбреНрд╕ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕рднреА рдХрд░реНрдордЪрд╛рд░реА рд╡реНрдпрд╕реНрдд рд╣реИрдВ, рддреЛ рд╣рдо рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рдХрддрд╛рд░ рдореЗрдВ рдЕрдиреБрд░реЛрдз рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред рдпрджрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдирд┐: рд╢реБрд▓реНрдХ рдирд┐рд╖реНрдХреНрд░рд┐рдп рдХрд░реНрдордЪрд╛рд░реА рд╣реИ, рддреЛ рд╣рдо рдлрд┐рд░ рд╕реЗ рдХрддрд╛рд░ рдореЗрдВ рдЕрдиреБрд░реЛрдз рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕ рдмрд╛рд░ рд╣рдо рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ (рд╕реНрдерд┐рддрд┐-рдЕрдзрд┐рд╕реВрдЪрд┐рдд (caar * рдирд┐рд╖реНрдХреНрд░рд┐рдп-рдХрд░реНрдордЪрд╛рд░реА *))ред рдФрд░ рддреАрд╕рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо рдмрд╕ рдПрдХ рдирдпрд╛ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдкрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕реЗ рд╢реНрд░рдорд┐рдХ-рдереНрд░реЗрдб рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рд╕рдм рдХреБрдЫ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИред рдпрд╣ рдХреЗрд╡рд▓ рд╢реНрд░рдорд┐рдХ рд╕реНрдЯреНрд░реАрдо рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдмрдиреА рд╣реБрдИ рд╣реИ:
(defun worker-thread (request-id socket idle-workers) (if request-id
рдпрджрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрдиреБрд░реЛрдз-рдЖрдИрдбреА рдХреЗ рд╕рд╛рде рдПрдХ рдХреЙрд▓ рдерд╛, рддреЛ рд╣рдореЗрдВ рдкрд╣рд▓реЗ рдЕрдиреБрд░реЛрдз рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╣рдо рдХреЗрд╡рд▓ рд╕рд╣рд╛рдпрдХ рдлрд╝рдВрдХреНрд╢рди http-рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рд╕реЙрдХреЗрдЯ рдХреЛ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред рдЕрдЧрд▓рд╛, рд╣рдо рдЬрд╛рдВрдЪрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдЕрдзрд┐рдХ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдЕрдиреБрд░реЛрдз рд╣реИрдВ: рдмрд╕ рдХрддрд╛рд░ рд╕реЗ рдкрд╣рд▓рд╛ рдЕрдиреБрд░реЛрдз рд╣рдЯрд╛ рджреЗрдВ рдФрд░ рдЗрд╕реЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпрдХрд░реНрддрд╛-рдереНрд░реЗрдб рдХреЛ рдкрд╛рд╕ рдХрд░реЗрдВ, рдЬрд┐рд╕рд╕реЗ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛-рдереНрд░реЗрдб рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкреБрдирд░рд╛рд╡рд░реНрддреА рд░реВрдк рд╕реЗ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред рд╕рд╡рд╛рд▓ рдЙрда рд╕рдХрддрд╛ рд╣реИ, "рдХреНрдпрд╛ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреА рд╕реАрдорд╛ рд╣реЛрдЧреА рдХреНрдпреЛрдВрдХрд┐ рд╕реНрдЯреИрдХ рдХрд┐рд╕реА рдмрд┐рдВрджреБ рдкрд░ рдУрд╡рд░рдлреНрд▓реЛ рд╣реЛрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬрдм рдХрддрд╛рд░ рдореЗрдВ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдЕрдиреБрд░реЛрдз рд╣реЛрддреЗ рд╣реИрдВ?" рдЪреВрдВрдХрд┐ рд╢реНрд░рдорд┐рдХ-рдереНрд░реЗрдб рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдХреБрдЫ рднреА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдирд╣реАрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рддрдм? рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рд╕реАрдорд╛ рдирд╣реАрдВ рд╣реЛрдЧреАред рд▓рдЧрднрдЧ рд╕рднреА рдЖрдзреБрдирд┐рдХ рдХреЙрдорди рд▓рд┐рд╕реНрдк рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЗрд╕ рдЕрдиреБрдХреВрд▓рди рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддреЗ рд╣реИрдВред рдЦреИрд░, рдЕрдЧрд░ рдХрддрд╛рд░ рдЦрд╛рд▓реА рд╣реИ, рддреЛ рд╣рдореЗрдВ рд╕рд┐рд░реНрдл рдирд┐рд╖реНрдХреНрд░рд┐рдп рд╢реНрд░рдорд┐рдХреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреА рд╣реЛрдЧреАред рдпрджрд┐ рд╣рдорд╛рд░реЗ рд╕рд╛рде рд╕рдм рдХреБрдЫ рдареАрдХ рд╣реИ, рддреЛ рд╣рдо рдмрд╕ рдЕрдиреБрд░реЛрдз рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдХреЛ рд╢реНрд░рдорд┐рдХреЛрдВ рдХреА рд╕реВрдЪреА рд╕реЗ рдирд┐рдХрд╛рд▓ рджреЗрддреЗ рд╣реИрдВред рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рд╣рдо рдПрдХ рд╢рд░реНрдд-рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЗрд╕ рддрд░рд╣ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдирд┐рд╖реНрдХреНрд░рд┐рдп рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдмрди рдЬрд╛рддрд╛ рд╣реИред
рдЕрдЧрд░ рдЖрдк рдЧреМрд░ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рд╕реВрдЪреА-рд╢реНрд░рдорд┐рдХреЛрдВ рдХреЛ рднреА рдХрд╣рддреЗ рд╣реИрдВред рдпрд╣ рдПрдХ рд╕рд╣рд╛рдпрдХ рдХрд╛рд░реНрдп рд╣реИ рдЬреЛ рдмрд╕ рдореГрдд рдзрд╛рдЧреЗ рдХреА рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рд╕реВрдЪреА рдХреЛ рд╕рд╛рдл рдХрд░рддрд╛ рд╣реИред
рдпрд╣ http- рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рд╕рдорд╛рд░реЛрд╣ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдмрдиреА рд╣реБрдИ рд╣реИ:
(defun http-worker (socket) (let* ((stream (socket-stream socket)) (request (myweb.util:parse-request stream))) (myweb.handler:process-request request stream) (finish-output stream) (socket-close socket))) (defun list-workers () (with-lock-held (*worker-mutex*) (setq *workers* (remove-if (lambda (w) (not (thread-alive-p w))) *workers*)) (setq *worker-num* (length *workers*)) *workers*))
рдпрд╣рд╛рдВ рд╣рдо рд╕реЙрдХреЗрдЯ-рд╕реНрдЯреНрд░реАрдо рдмрдирд╛рддреЗ рд╣реИрдВ, рдЕрдиреБрд░реЛрдз рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ myweb.handler рдкрд░ рднреЗрдЬрддреЗ рд╣реИрдВ: рдкреНрд░рдХреНрд░рд┐рдпрд╛-рдЕрдиреБрд░реЛрдз (рд╣рдо рджреВрд╕рд░реЗ рднрд╛рдЧ рдореЗрдВ рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗ)ред рд╕реВрдЪреА-рд╢реНрд░рдорд┐рдХреЛрдВ рдиреЗ рд╣рдореЗрдВ рд╢реНрд░рдорд┐рдХреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рджреА рд╣реИ, рдкрд╣рд▓реЗ рдЗрд╕реЗ рдореГрдд рдереНрд░реЗрдбреНрд╕ рдХреЛ рд╕рд╛рдлрд╝ рдХрд░рдирд╛ рд╣реИред рд╣рдо рдЗрд╕ рдХрд╛рд░реНрдп рдХреЛ рд╕реНрдерд┐рддрд┐-рдкреНрд░рддреАрдХреНрд╖рд╛ рд╕реЗ рдкрд╣рд▓реЗ рдХрд╛рд░реНрдпрдХрд░реНрддрд╛-рд╕реВрддреНрд░ рдореЗрдВ рдХрд╣рддреЗ рд╣реИрдВред
рдЖрдЦрд┐рд░реА рдЪреАрдЬ рдЬреЛ рд╣рдореЗрдВ рдХрд░рдиреЗ рдХреА рдЬрд╝рд░реВрд░рдд рд╣реИ рд╡рд╣ рд╣реИ рд╕реНрдЯреЙрдк-http рдлрд╝рдВрдХреНрд╢рди, рдЬреЛ рд╣рдорд╛рд░реЗ рд╡реЗрдм рд╕рд░реНрд╡рд░ рдХреЛ рд░реЛрдХ рджреЗрдЧрд╛:
(defun stop-http () (if *listen-socket* (progn (stop-thread) (socket-close *listen-socket*) (setq *listen-socket* nil) (setq *request-queue* nil) (setq *worker-num* 0) (setq *workers* nil) (mapcar (lambda (i) (destroy-thread (cdr i))) *idle-workers*) (setq *idle-workers-num* 0) (setq *idle-workers* nil) (release-lock *worker-mutex*) (setq *request-threads* nil) (release-lock *request-mutex*) (setq *request-mutex* (make-lock "request-mutex")) (setq *worker-mutex* (make-lock "worker-mutex"))))) (defun stop-thread () (if (and *listen-thread* (thread-alive-p *listen-thread*)) (destroy-thread *listen-thread*)))
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рд╣реИ - рд╣рдо рдорд╢реАрди рдкреНрд░рд╡рд╛рд╣ рдХреЛ рд░реЛрдХрддреЗ рд╣реИрдВ, рд╕рднреА рд╢реНрд░рдорд┐рдХреЛрдВ рдХреЛ рдорд╛рд░рддреЗ рд╣реИрдВ рдФрд░ рд╕реВрдЪрд┐рдпреЛрдВ рдХреЛ рд╢реВрдиреНрдп рдХрд░рддреЗ рд╣реИрдВред
рдФрд░ рдЗрд╕рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдм рдХреБрдЫ рддреИрдпрд╛рд░ рд╣реИред рд╣рдо рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ
рджреВрд╕рд░реЗ рднрд╛рдЧ рдореЗрдВ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗред
рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!
PS рд╡рд░реНрддрдиреА рдФрд░ рд▓реЗрдЖрдЙрдЯ рдХреЗ рд╕рд╛рде рдорджрдж рдХреЗ рд▓рд┐рдП
ertaquo рдзрдиреНрдпрд╡рд╛рдж