├── eBook ├── .#07.2.md ├── images │ ├── 1.3.go.png │ ├── cover.png │ ├── ebook.jpg │ ├── navi1.png │ ├── navi10.png │ ├── navi11.png │ ├── navi12.png │ ├── navi13.png │ ├── navi14.png │ ├── navi2.png │ ├── navi3.png │ ├── navi4.png │ ├── navi5.png │ ├── navi6.png │ ├── navi7.png │ ├── navi8.png │ ├── navi9.png │ ├── 1.1.cmd.png │ ├── 1.1.linux.png │ ├── 1.1.mac.png │ ├── 1.4.emacs.png │ ├── 1.4.idea1.png │ ├── 1.4.idea2.png │ ├── 1.4.idea3.png │ ├── 1.4.idea4.png │ ├── 1.4.idea5.png │ ├── 1.4.vim.png │ ├── 13.1.flow.png │ ├── 2.2.array.png │ ├── 2.2.basic.png │ ├── 2.2.slice.png │ ├── 2.3.init.png │ ├── 3.1.dns2.png │ ├── 3.1.http.png │ ├── 3.1.web.png │ ├── 3.1.web2.png │ ├── 3.2.goweb.png │ ├── 3.3.http.png │ ├── 4.1.login.png │ ├── 4.1.slice.png │ ├── 4.4.token.png │ ├── 8.3.rest.png │ ├── 8.3.rest2.png │ ├── 8.3.rest3.png │ ├── 8.4.rpc.png │ ├── 9.1.csrf.png │ ├── polling.png │ ├── 1.4.liteide.png │ ├── 13.1.gopath.png │ ├── 13.4.beego.png │ ├── 14.4.github.png │ ├── 14.6.pprof.png │ ├── 14.6.pprof2.png │ ├── 14.6.pprof3.png │ ├── 2.2.makenew.png │ ├── 2.2.slice2.png │ ├── 4.3.escape.png │ ├── 4.5.upload.png │ ├── 4.5.upload2.png │ ├── 5.6.mongodb.png │ ├── 6.1.cookie.png │ ├── 6.1.cookie2.png │ ├── 6.1.session.png │ ├── 6.4.cookie.png │ ├── 6.4.hijack.png │ ├── 8.1.socket.png │ ├── 1.4.eclipse1.png │ ├── 1.4.eclipse2.png │ ├── 1.4.eclipse3.png │ ├── 1.4.eclipse4.png │ ├── 1.4.eclipse5.png │ ├── 1.4.eclipse6.png │ ├── 1.4.sublime1.png │ ├── 1.4.sublime2.png │ ├── 1.4.sublime3.png │ ├── 1.4.sublime4.png │ ├── 13.1.gopath2.png │ ├── 14.1.bootstrap.png │ ├── 14.4.github2.png │ ├── 14.4.github3.png │ ├── 3.1.httpPOST.png │ ├── 3.1.response.png │ ├── 6.4.setcookie.png │ ├── 7.4.template.png │ ├── 8.2.websocket.png │ ├── 8.2.websocket2.png │ ├── 8.2.websocket3.png │ ├── 14.1.bootstrap2.png │ ├── 14.1.bootstrap3.png │ ├── 3.1.dns_hierachy.png │ ├── 3.1.dns_inquery.png │ ├── 3.3.illustrator.png │ ├── 2.4.student_struct.png │ ├── 6.4.hijacksuccess.png │ ├── 2.5.rect_func_without_receiver.png │ ├── 2.5.shapes_func_with_receiver_cp.png │ └── 2.5.shapes_func_without_receiver.png ├── 03.5.md ├── 03.0.md ├── 07.7.md ├── 04.6.md ├── ref.md ├── 05.7.md ├── 10.4.md ├── 06.5.md ├── 01.5.md ├── 13.6.md ├── 02.0.md ├── 11.4.md ├── 08.5.md ├── 09.7.md ├── 05.0.md ├── 06.0.md ├── 12.5.md ├── 07.0.md ├── 12.0.md ├── 02.8.md ├── 01.0.md ├── 14.0.md ├── 13.0.md ├── 14.7.md ├── 04.0.md ├── 09.0.md ├── 08.0.md ├── 10.0.md ├── 11.0.md ├── 03.2.md ├── 04.4.md ├── 04.3.md ├── 02.1.md ├── 14.5.md ├── preface.md ├── 05.3.md ├── 14.6.md ├── 14.2.md ├── 07.5.md ├── 14.1.md ├── 05.4.md ├── 05.6.md ├── 03.3.md ├── 05.2.md ├── 06.3.md └── 07.6.md ├── code ├── src │ ├── apps │ │ ├── ch.5.3 │ │ │ ├── foo.db │ │ │ ├── schema.sql │ │ │ ├── readme.md │ │ │ └── main.go │ │ ├── ch.2.3 │ │ │ ├── import_packages │ │ │ │ ├── only_call_init │ │ │ │ │ └── only_call_init.go │ │ │ │ └── main.go │ │ │ ├── hidden_print_methods │ │ │ │ └── main.go │ │ │ ├── variadic_functions │ │ │ │ └── main.go │ │ │ ├── basic_functions │ │ │ │ └── main.go │ │ │ ├── panic_and_recover │ │ │ │ └── main.go │ │ │ ├── pass_by_value_and_pointer │ │ │ │ └── main.go │ │ │ ├── type_function │ │ │ │ └── main.go │ │ │ └── main.go │ │ ├── ch.5.2 │ │ │ ├── schema.sql │ │ │ ├── readme.md │ │ │ └── main.go │ │ ├── ch.2.2 │ │ │ └── what_is_wrong_with_this │ │ │ │ └── main.go │ │ ├── ch.5.4 │ │ │ ├── schema.sql │ │ │ ├── readme.md │ │ │ └── main.go │ │ ├── ch.5.6 │ │ │ ├── mongodb │ │ │ │ ├── readme.md │ │ │ │ └── main.go │ │ │ └── redis │ │ │ │ ├── readme.md │ │ │ │ └── main.go │ │ ├── ch.4.1 │ │ │ ├── login.gtpl │ │ │ └── main.go │ │ ├── ch.4.2 │ │ │ ├── submission.gtpl │ │ │ ├── main.go │ │ │ └── profile.gtpl │ │ ├── ch.5.5 │ │ │ ├── schema.sql │ │ │ ├── readme.md │ │ │ └── main.go │ │ ├── ch.2.7 │ │ │ ├── buffered_channel │ │ │ │ └── main.go │ │ │ ├── goroutine │ │ │ │ └── main.go │ │ │ ├── range_and_close_channel │ │ │ │ └── main.go │ │ │ ├── timeout │ │ │ │ └── main.go │ │ │ ├── unbuffered_channel │ │ │ │ └── main.go │ │ │ └── select_channel │ │ │ │ └── main.go │ │ ├── ch.4.5 │ │ │ ├── upload.gtpl │ │ │ ├── index.gtpl │ │ │ ├── client_upload │ │ │ │ └── main.go │ │ │ ├── nonce │ │ │ │ └── main.go │ │ │ └── main.go │ │ ├── ch.4.4 │ │ │ ├── submission.gtpl │ │ │ ├── main.go │ │ │ ├── nonce │ │ │ │ └── main.go │ │ │ └── profile.gtpl │ │ ├── ch.2.5 │ │ │ ├── pass_struct_to_method │ │ │ │ └── main.go │ │ │ ├── embedded_method │ │ │ │ └── main.go │ │ │ ├── attach_methods_to_struct │ │ │ │ └── main.go │ │ │ ├── method_overload │ │ │ │ └── main.go │ │ │ └── box_example │ │ │ │ └── main.go │ │ ├── ch.2.1 │ │ │ └── main.go │ │ ├── ch.2.6 │ │ │ ├── stringer_interface │ │ │ │ └── main.go │ │ │ ├── reflection │ │ │ │ └── main.go │ │ │ ├── switch_type_check │ │ │ │ └── main.go │ │ │ ├── type_check │ │ │ │ └── main.go │ │ │ └── interface │ │ │ │ └── main.go │ │ ├── ch.1.2 │ │ │ └── main.go │ │ ├── ch.3.4 │ │ │ └── main.go │ │ ├── ch.2.4 │ │ │ ├── embedded_structs_with_name_conflict │ │ │ │ └── main.go │ │ │ ├── main.go │ │ │ ├── embedded_structs │ │ │ │ └── main.go │ │ │ ├── embedded_structs2 │ │ │ │ └── main.go │ │ │ └── compare_age │ │ │ │ └── main.go │ │ ├── ch.4.3 │ │ │ ├── index.gtpl │ │ │ └── main.go │ │ └── ch.3.2 │ │ │ └── main.go │ └── mymath │ │ └── sqrt.go └── readme.md └── README.md /eBook/.#07.2.md: -------------------------------------------------------------------------------- 1 | jackgris@jackgris-note.2580:1427929930 -------------------------------------------------------------------------------- /eBook/images/1.3.go.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/1.3.go.png -------------------------------------------------------------------------------- /eBook/images/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/cover.png -------------------------------------------------------------------------------- /eBook/images/ebook.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/ebook.jpg -------------------------------------------------------------------------------- /eBook/images/navi1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/navi1.png -------------------------------------------------------------------------------- /eBook/images/navi10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/navi10.png -------------------------------------------------------------------------------- /eBook/images/navi11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/navi11.png -------------------------------------------------------------------------------- /eBook/images/navi12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/navi12.png -------------------------------------------------------------------------------- /eBook/images/navi13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/navi13.png -------------------------------------------------------------------------------- /eBook/images/navi14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/navi14.png -------------------------------------------------------------------------------- /eBook/images/navi2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/navi2.png -------------------------------------------------------------------------------- /eBook/images/navi3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/navi3.png -------------------------------------------------------------------------------- /eBook/images/navi4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/navi4.png -------------------------------------------------------------------------------- /eBook/images/navi5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/navi5.png -------------------------------------------------------------------------------- /eBook/images/navi6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/navi6.png -------------------------------------------------------------------------------- /eBook/images/navi7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/navi7.png -------------------------------------------------------------------------------- /eBook/images/navi8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/navi8.png -------------------------------------------------------------------------------- /eBook/images/navi9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/navi9.png -------------------------------------------------------------------------------- /eBook/images/1.1.cmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/1.1.cmd.png -------------------------------------------------------------------------------- /eBook/images/1.1.linux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/1.1.linux.png -------------------------------------------------------------------------------- /eBook/images/1.1.mac.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/1.1.mac.png -------------------------------------------------------------------------------- /eBook/images/1.4.emacs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/1.4.emacs.png -------------------------------------------------------------------------------- /eBook/images/1.4.idea1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/1.4.idea1.png -------------------------------------------------------------------------------- /eBook/images/1.4.idea2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/1.4.idea2.png -------------------------------------------------------------------------------- /eBook/images/1.4.idea3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/1.4.idea3.png -------------------------------------------------------------------------------- /eBook/images/1.4.idea4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/1.4.idea4.png -------------------------------------------------------------------------------- /eBook/images/1.4.idea5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/1.4.idea5.png -------------------------------------------------------------------------------- /eBook/images/1.4.vim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/1.4.vim.png -------------------------------------------------------------------------------- /eBook/images/13.1.flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/13.1.flow.png -------------------------------------------------------------------------------- /eBook/images/2.2.array.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/2.2.array.png -------------------------------------------------------------------------------- /eBook/images/2.2.basic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/2.2.basic.png -------------------------------------------------------------------------------- /eBook/images/2.2.slice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/2.2.slice.png -------------------------------------------------------------------------------- /eBook/images/2.3.init.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/2.3.init.png -------------------------------------------------------------------------------- /eBook/images/3.1.dns2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/3.1.dns2.png -------------------------------------------------------------------------------- /eBook/images/3.1.http.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/3.1.http.png -------------------------------------------------------------------------------- /eBook/images/3.1.web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/3.1.web.png -------------------------------------------------------------------------------- /eBook/images/3.1.web2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/3.1.web2.png -------------------------------------------------------------------------------- /eBook/images/3.2.goweb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/3.2.goweb.png -------------------------------------------------------------------------------- /eBook/images/3.3.http.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/3.3.http.png -------------------------------------------------------------------------------- /eBook/images/4.1.login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/4.1.login.png -------------------------------------------------------------------------------- /eBook/images/4.1.slice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/4.1.slice.png -------------------------------------------------------------------------------- /eBook/images/4.4.token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/4.4.token.png -------------------------------------------------------------------------------- /eBook/images/8.3.rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/8.3.rest.png -------------------------------------------------------------------------------- /eBook/images/8.3.rest2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/8.3.rest2.png -------------------------------------------------------------------------------- /eBook/images/8.3.rest3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/8.3.rest3.png -------------------------------------------------------------------------------- /eBook/images/8.4.rpc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/8.4.rpc.png -------------------------------------------------------------------------------- /eBook/images/9.1.csrf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/9.1.csrf.png -------------------------------------------------------------------------------- /eBook/images/polling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/polling.png -------------------------------------------------------------------------------- /code/src/apps/ch.5.3/foo.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/code/src/apps/ch.5.3/foo.db -------------------------------------------------------------------------------- /eBook/images/1.4.liteide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/1.4.liteide.png -------------------------------------------------------------------------------- /eBook/images/13.1.gopath.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/13.1.gopath.png -------------------------------------------------------------------------------- /eBook/images/13.4.beego.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/13.4.beego.png -------------------------------------------------------------------------------- /eBook/images/14.4.github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/14.4.github.png -------------------------------------------------------------------------------- /eBook/images/14.6.pprof.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/14.6.pprof.png -------------------------------------------------------------------------------- /eBook/images/14.6.pprof2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/14.6.pprof2.png -------------------------------------------------------------------------------- /eBook/images/14.6.pprof3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/14.6.pprof3.png -------------------------------------------------------------------------------- /eBook/images/2.2.makenew.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/2.2.makenew.png -------------------------------------------------------------------------------- /eBook/images/2.2.slice2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/2.2.slice2.png -------------------------------------------------------------------------------- /eBook/images/4.3.escape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/4.3.escape.png -------------------------------------------------------------------------------- /eBook/images/4.5.upload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/4.5.upload.png -------------------------------------------------------------------------------- /eBook/images/4.5.upload2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/4.5.upload2.png -------------------------------------------------------------------------------- /eBook/images/5.6.mongodb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/5.6.mongodb.png -------------------------------------------------------------------------------- /eBook/images/6.1.cookie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/6.1.cookie.png -------------------------------------------------------------------------------- /eBook/images/6.1.cookie2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/6.1.cookie2.png -------------------------------------------------------------------------------- /eBook/images/6.1.session.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/6.1.session.png -------------------------------------------------------------------------------- /eBook/images/6.4.cookie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/6.4.cookie.png -------------------------------------------------------------------------------- /eBook/images/6.4.hijack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/6.4.hijack.png -------------------------------------------------------------------------------- /eBook/images/8.1.socket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/8.1.socket.png -------------------------------------------------------------------------------- /eBook/images/1.4.eclipse1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/1.4.eclipse1.png -------------------------------------------------------------------------------- /eBook/images/1.4.eclipse2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/1.4.eclipse2.png -------------------------------------------------------------------------------- /eBook/images/1.4.eclipse3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/1.4.eclipse3.png -------------------------------------------------------------------------------- /eBook/images/1.4.eclipse4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/1.4.eclipse4.png -------------------------------------------------------------------------------- /eBook/images/1.4.eclipse5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/1.4.eclipse5.png -------------------------------------------------------------------------------- /eBook/images/1.4.eclipse6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/1.4.eclipse6.png -------------------------------------------------------------------------------- /eBook/images/1.4.sublime1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/1.4.sublime1.png -------------------------------------------------------------------------------- /eBook/images/1.4.sublime2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/1.4.sublime2.png -------------------------------------------------------------------------------- /eBook/images/1.4.sublime3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/1.4.sublime3.png -------------------------------------------------------------------------------- /eBook/images/1.4.sublime4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/1.4.sublime4.png -------------------------------------------------------------------------------- /eBook/images/13.1.gopath2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/13.1.gopath2.png -------------------------------------------------------------------------------- /eBook/images/14.1.bootstrap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/14.1.bootstrap.png -------------------------------------------------------------------------------- /eBook/images/14.4.github2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/14.4.github2.png -------------------------------------------------------------------------------- /eBook/images/14.4.github3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/14.4.github3.png -------------------------------------------------------------------------------- /eBook/images/3.1.httpPOST.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/3.1.httpPOST.png -------------------------------------------------------------------------------- /eBook/images/3.1.response.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/3.1.response.png -------------------------------------------------------------------------------- /eBook/images/6.4.setcookie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/6.4.setcookie.png -------------------------------------------------------------------------------- /eBook/images/7.4.template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/7.4.template.png -------------------------------------------------------------------------------- /eBook/images/8.2.websocket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/8.2.websocket.png -------------------------------------------------------------------------------- /eBook/images/8.2.websocket2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/8.2.websocket2.png -------------------------------------------------------------------------------- /eBook/images/8.2.websocket3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/8.2.websocket3.png -------------------------------------------------------------------------------- /eBook/images/14.1.bootstrap2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/14.1.bootstrap2.png -------------------------------------------------------------------------------- /eBook/images/14.1.bootstrap3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/14.1.bootstrap3.png -------------------------------------------------------------------------------- /eBook/images/3.1.dns_hierachy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/3.1.dns_hierachy.png -------------------------------------------------------------------------------- /eBook/images/3.1.dns_inquery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/3.1.dns_inquery.png -------------------------------------------------------------------------------- /eBook/images/3.3.illustrator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/3.3.illustrator.png -------------------------------------------------------------------------------- /eBook/images/2.4.student_struct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/2.4.student_struct.png -------------------------------------------------------------------------------- /eBook/images/6.4.hijacksuccess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/6.4.hijacksuccess.png -------------------------------------------------------------------------------- /eBook/images/2.5.rect_func_without_receiver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/2.5.rect_func_without_receiver.png -------------------------------------------------------------------------------- /eBook/images/2.5.shapes_func_with_receiver_cp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/2.5.shapes_func_with_receiver_cp.png -------------------------------------------------------------------------------- /eBook/images/2.5.shapes_func_without_receiver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackgris/build-web-application-with-golang_ES/HEAD/eBook/images/2.5.shapes_func_without_receiver.png -------------------------------------------------------------------------------- /code/src/apps/ch.2.3/import_packages/only_call_init/only_call_init.go: -------------------------------------------------------------------------------- 1 | package only_call_init 2 | 3 | import "fmt" 4 | 5 | func init() { 6 | fmt.Println("only_call_init.init() was called.") 7 | } 8 | -------------------------------------------------------------------------------- /code/src/apps/ch.5.3/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `userinfo` ( 2 | `uid` INTEGER PRIMARY KEY AUTOINCREMENT, 3 | `username` VARCHAR(64) NULL, 4 | `department` VARCHAR(64) NULL, 5 | `created` DATE NULL 6 | ); 7 | -------------------------------------------------------------------------------- /code/readme.md: -------------------------------------------------------------------------------- 1 | ## Workspace setup. 2 | 3 | To avoid workspace issues and be able to develop from any folder within this path, 4 | set the environment variable `GOPATH` to the path of this directory. 5 | 6 | More info: 7 | - [GOPATH documentation](http://golang.org/doc/code.html#GOPATH) 8 | -------------------------------------------------------------------------------- /code/src/apps/ch.5.2/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `userinfo` ( 2 | `uid` INT(10) NOT NULL AUTO_INCREMENT, 3 | `username` VARCHAR(64) NULL DEFAULT NULL, 4 | `departname` VARCHAR(64) NULL DEFAULT NULL, 5 | `created` DATE NULL DEFAULT NULL, 6 | PRIMARY KEY (`uid`) 7 | ); 8 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.2/what_is_wrong_with_this/main.go: -------------------------------------------------------------------------------- 1 | //Código de ejemplo para el capítulo 2.2 de "Creando una aplicación Web con Golang" 2 | //Objetivo: Tratar de solucionar este programa. 3 | // Desde la consola, escriba `go run main.go` 4 | package main 5 | 6 | func main() { 7 | var i int 8 | } 9 | -------------------------------------------------------------------------------- /code/src/apps/ch.5.4/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE userinfo 2 | ( 3 | uid serial NOT NULL, 4 | username character varying(100) NOT NULL, 5 | departname character varying(500) NOT NULL, 6 | Created date, 7 | CONSTRAINT userinfo_pkey PRIMARY KEY (uid) 8 | ) 9 | WITH (OIDS=FALSE); 10 | -------------------------------------------------------------------------------- /code/src/apps/ch.5.6/mongodb/readme.md: -------------------------------------------------------------------------------- 1 | ##Setup for `ch.5.6` for MongoDB 2 | 3 | - Step 1) Install and run MongoDB 4 | - Step 2) Launch the MongoDB daemon (mongod) to start the server. 5 | - Step 3) Run `go get` to download and install the remote packages. 6 | - Step 4) Execute the program with `go run main.go` 7 | -------------------------------------------------------------------------------- /code/src/apps/ch.4.1/login.gtpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | Username: 8 | Password: 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /code/src/apps/ch.4.2/submission.gtpl: -------------------------------------------------------------------------------- 1 | {{define "submission"}} 2 | 3 | 4 | {{if .Errors}} 5 |

Errors:

6 |
    7 | {{range .Errors}} 8 |
  1. {{.}}
  2. 9 | {{end}} 10 |
11 | {{else}} 12 | Profile successfully submitted. 13 | {{end}} 14 | 15 | 16 | {{end}} -------------------------------------------------------------------------------- /code/src/apps/ch.5.5/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `userinfo` ( 2 | `uid` INTEGER PRIMARY KEY AUTOINCREMENT, 3 | `username` VARCHAR(64) NULL, 4 | `department` VARCHAR(64) NULL, 5 | `created` DATE NULL 6 | ); 7 | CREATE TABLE `userdetail` ( 8 | `uid` INT(10) NULL, 9 | `intro` TEXT NULL, 10 | `profile` TEXT NULL, 11 | PRIMARY KEY (`uid`) 12 | ); 13 | -------------------------------------------------------------------------------- /code/src/apps/ch.5.6/redis/readme.md: -------------------------------------------------------------------------------- 1 | ##Setup for `ch.5.6` for Redis 2 | 3 | - Step 1) Install and run Redis 4 | - Step 2) Launch the Redis server matching the DB constants. 5 | 6 | DB_PORT = "9191" 7 | DB_URL = "127.0.0.1" 8 | 9 | - Step 3) Run `go get` to download and install the remote packages. 10 | - Step 4) Execute the program with `go run main.go` 11 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.7/buffered_channel/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 2.7 from "Build Web Application with Golang" 2 | // Purpose: Shows how to use a buffered channel 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | c := make(chan int, 2) // change 2 to 1 will have runtime error, but 3 is fine 9 | c <- 1 10 | c <- 2 11 | fmt.Println(<-c) 12 | fmt.Println(<-c) 13 | } 14 | -------------------------------------------------------------------------------- /code/src/apps/ch.4.5/upload.gtpl: -------------------------------------------------------------------------------- 1 | {{define "upload"}} 2 | 3 | 4 | {{if .Errors}} 5 |

Errors:

6 |
    7 | {{range .Errors}} 8 |
  1. {{.}}
  2. 9 | {{end}} 10 |
11 | {{else}} 12 | File uploaded successfully.
13 | Note: Refreshing the page will produce a duplicate entry. 14 | {{end}} 15 | 16 | 17 | {{end}} 18 | -------------------------------------------------------------------------------- /code/src/apps/ch.4.4/submission.gtpl: -------------------------------------------------------------------------------- 1 | {{define "submission"}} 2 | 3 | 4 | {{if .Errors}} 5 |

Errors:

6 |
    7 | {{range .Errors}} 8 |
  1. {{.}}
  2. 9 | {{end}} 10 |
11 | {{else}} 12 | Profile successfully submitted.
13 | Note: Refreshing the page will produce a duplicate entry. 14 | {{end}} 15 | 16 | 17 | {{end}} -------------------------------------------------------------------------------- /code/src/apps/ch.2.3/hidden_print_methods/main.go: -------------------------------------------------------------------------------- 1 | // As of Google go 1.1.2, `println()` and `print()` are hidden functions included from the runtime package. 2 | // However it's encouraged to use the print functions from the `fmt` package. 3 | package main 4 | 5 | import "fmt" 6 | 7 | func f() { 8 | fmt.Println("First") 9 | print("Second ") 10 | println(" Third") 11 | } 12 | func main() { 13 | f() 14 | } 15 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.5/pass_struct_to_method/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Rectangle struct { 6 | width, height float64 7 | } 8 | 9 | func area(r Rectangle) float64 { 10 | return r.width * r.height 11 | } 12 | 13 | func main() { 14 | r1 := Rectangle{12, 2} 15 | r2 := Rectangle{9, 4} 16 | fmt.Println("Area of r1 is: ", area(r1)) 17 | fmt.Println("Area of r2 is: ", area(r2)) 18 | } 19 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.1/main.go: -------------------------------------------------------------------------------- 1 | // Código de ejemplo para el capítulo? de "Build aplicación Web con Golang" 2 | // Propósito: ejemplo Hola mundo demostrando soporte UTF-8. 3 | // Para ejecutar en la consola, escriba `go run main.go 4 | // No debe ver cuadrados o signos de interrogación 5 | package main 6 | 7 | import "fmt" 8 | 9 | func main() { 10 | fmt.Printf("Hello, world or 你好,世界 or καλημ ́ρα κóσμ or こんにちは世界\n") 11 | } 12 | -------------------------------------------------------------------------------- /code/src/mymath/sqrt.go: -------------------------------------------------------------------------------- 1 | // Código de ejemplo para el capítulo 1.2 del "Build aplicación Web con Golang" 2 | // Objetivo: Muestra cómo crear un paquete sencillo llamado `MyMath` 3 | // Este paquete puede ser importado de otro archivo para que funcione. 4 | package mymath 5 | 6 | func Sqrt(x float64) float64 { 7 | z := 0.0 8 | for i := 0; i < 1000; i++ { 9 | z -= (z*z - x) / (2 * x) 10 | } 11 | return z 12 | } 13 | -------------------------------------------------------------------------------- /code/src/apps/ch.4.5/index.gtpl: -------------------------------------------------------------------------------- 1 | {{define "index"}} 2 | 3 | 4 | 5 | Upload file 6 | 7 | 8 |
9 | 10 | 11 | 12 |
13 | 14 | 15 | {{end}} 16 | -------------------------------------------------------------------------------- /code/src/apps/ch.5.2/readme.md: -------------------------------------------------------------------------------- 1 | ##Setup for `ch.5.2` 2 | 3 | - Step 1) Install and run MySql 4 | - Step 2) Create a user and database according to the constants in `main.go` 5 | 6 | DB_USER = "user" 7 | DB_PASSWORD = "" 8 | DB_NAME = "test" 9 | 10 | - Step 3) Create table `userinfo` located at `schema.sql` 11 | - Step 4) Run `go get` to download and install the remote packages. 12 | - Step 5) Execute the program with `go run main.go` 13 | -------------------------------------------------------------------------------- /code/src/apps/ch.5.4/readme.md: -------------------------------------------------------------------------------- 1 | ##Setup for ch.5.4 2 | 3 | - Step 1) Install and run Postgres 4 | - Step 2) Create a user and database according to the constants in `main.go` 5 | 6 | DB_USER = "user" 7 | DB_PASSWORD = "" 8 | DB_NAME = "test" 9 | 10 | - Step 3) Create table `userinfo` located at `schema.sql` 11 | - Step 4) Run `go get` to download and install the remote packages. 12 | - Step 5) Execute the program with `go run main.go` 13 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.7/goroutine/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 2.7 from "Build Web Application with Golang" 2 | // Purpose: Shows how to launch a simple gorountine 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "runtime" 8 | ) 9 | 10 | func say(s string) { 11 | for i := 0; i < 5; i++ { 12 | runtime.Gosched() 13 | fmt.Println(s) 14 | } 15 | } 16 | 17 | func main() { 18 | go say("world") // create a new goroutine 19 | say("hello") // current goroutine 20 | } 21 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.6/stringer_interface/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | type Human struct { 9 | name string 10 | age int 11 | phone string 12 | } 13 | 14 | // Human implemented fmt.Stringer 15 | func (h Human) String() string { 16 | return "Name:" + h.name + ", Age:" + strconv.Itoa(h.age) + " years, Contact:" + h.phone 17 | } 18 | 19 | func main() { 20 | Bob := Human{"Bob", 39, "000-7777-XXX"} 21 | fmt.Println("This Human is : ", Bob) 22 | } 23 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.7/range_and_close_channel/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 2.7 from "Build Web Application with Golang" 2 | // Purpose: Shows how to close and interate through a channel 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | ) 8 | 9 | func fibonacci(n int, c chan int) { 10 | x, y := 1, 1 11 | for i := 0; i < n; i++ { 12 | c <- x 13 | x, y = y, x+y 14 | } 15 | close(c) 16 | } 17 | 18 | func main() { 19 | c := make(chan int, 10) 20 | go fibonacci(cap(c), c) 21 | for i := range c { 22 | fmt.Println(i) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.7/timeout/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 2.7 from "Build Web Application with Golang" 2 | // Purpose: Shows how to create and use a timeout 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "time" 8 | ) 9 | 10 | 11 | func main() { 12 | c := make(chan int) 13 | o := make(chan bool) 14 | go func() { 15 | for { 16 | select { 17 | case v := <-c: 18 | fmt.Println(v) 19 | case <-time.After(5 * time.Second): 20 | fmt.Println("timeout") 21 | o <- true 22 | break 23 | } 24 | } 25 | }() 26 | <-o 27 | } 28 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.3/variadic_functions/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 2.3 from "Build Web Application with Golang" 2 | // Purpose: Shows how to return multiple values from a function 3 | package main 4 | 5 | import "fmt" 6 | 7 | // return results of A + B and A * B 8 | func SumAndProduct(A, B int) (int, int) { 9 | return A + B, A * B 10 | } 11 | 12 | func main() { 13 | x := 3 14 | y := 4 15 | 16 | xPLUSy, xTIMESy := SumAndProduct(x, y) 17 | 18 | fmt.Printf("%d + %d = %d\n", x, y, xPLUSy) 19 | fmt.Printf("%d * %d = %d\n", x, y, xTIMESy) 20 | } 21 | -------------------------------------------------------------------------------- /code/src/apps/ch.5.3/readme.md: -------------------------------------------------------------------------------- 1 | ## Set up for `ch.5.3` 2 | 3 | - Step 1) Download and install sqlite 3. 4 | - Step 2) Run `sqlite3 foo.db` to create a databased called `foo`. 5 | - Step 3) Create the `userinfo` table in sqlite using `schema.sql`. 6 | 7 | Read and run sql statements 8 | 9 | sqlite> .read schema.sql 10 | 11 | Show tables 12 | 13 | sqlite> .tables 14 | userinfo 15 | 16 | 17 | - Step 4) Exit sqlite. 18 | 19 | sqlite> .exit 20 | 21 | - Step 5) Run `go get` to download and install remote packages. 22 | - Step 6) Run the program with `go run main.go` 23 | 24 | -------------------------------------------------------------------------------- /code/src/apps/ch.1.2/main.go: -------------------------------------------------------------------------------- 1 | //Código de ejemplo para el capítulo 1.2 del "Build aplicación Web con Golang" 2 | //Propósito: Ejecute el archivo para comprobar si el espacio de trabajo está correctamente configurado. 3 | // Para ejecutar, vaya al directorio actual en una consola y teclear `go run main.go 4 | // Si no se muestra el texto "Hello World", la configuración no esta bien. 5 | package main 6 | 7 | import ( 8 | "fmt" 9 | "mymath" //este paquete debe estar ya creado 10 | ) 11 | 12 | func main() { 13 | fmt.Printf("Hello, world. Sqrt(2) = %v\n", mymath.Sqrt(2)) 14 | } 15 | -------------------------------------------------------------------------------- /code/src/apps/ch.5.5/readme.md: -------------------------------------------------------------------------------- 1 | ## Set up for `ch.5.5` 2 | 3 | - Step 1) Download and install sqlite 3. 4 | - Step 2) Run `sqlite3 foo.db` to create a databased called `foo`. 5 | - Step 3) Create the tables found in `schema.sql` in sqlite. 6 | 7 | Read and run sql statements 8 | 9 | sqlite> .read schema.sql 10 | 11 | Show tables 12 | 13 | sqlite> .tables 14 | userinfo 15 | userdetail 16 | 17 | - Step 4) Exit sqlite. 18 | 19 | sqlite> .exit 20 | 21 | - Step 5) Run `go get` to download and install remote packages. 22 | - Step 6) Run the program with `go run main.go` 23 | 24 | -------------------------------------------------------------------------------- /eBook/03.5.md: -------------------------------------------------------------------------------- 1 | # 3.5 Resumen 2 | 3 | En este capítulo, presentamos HTTP, el flujo de la resolución DNS y cómo construir un servidor Web simple. Entonces hablamos de cómo Go implementa servidor web para nosotros al ver el código fuente del paquete net/http. 4 | 5 | Espero que ahora conozca mucho más sobre el desarrollo web, y usted debería ver que es muy fácil y flexible crear una aplicación web en Go. 6 | 7 | ## Enlaces 8 | 9 | - [Indice](preface.md) 10 | - Sección anterior: [Obteniendo el paquete http](03.4.md) 11 | - Siguiente sección: [Formulario de entrada de los usuario](04.0.md) 12 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.7/unbuffered_channel/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 2.7 from "Build Web Application with Golang" 2 | // Purpose: Shows how to create and use a unbuffered channel 3 | package main 4 | 5 | import "fmt" 6 | 7 | func sum(a []int, c chan int) { 8 | total := 0 9 | for _, v := range a { 10 | total += v 11 | } 12 | c <- total // send total to c 13 | } 14 | 15 | func main() { 16 | a := []int{7, 2, 8, -9, 4, 0} 17 | 18 | c := make(chan int) 19 | go sum(a[:len(a)/2], c) 20 | go sum(a[len(a)/2:], c) 21 | x, y := <-c, <-c // receive from c 22 | 23 | fmt.Println(x, y, x+y) 24 | } 25 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.7/select_channel/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 2.7 from "Build Web Application with Golang" 2 | // Purpose: Shows how to use `select` 3 | package main 4 | 5 | import "fmt" 6 | 7 | func fibonacci(c, quit chan int) { 8 | x, y := 1, 1 9 | for { 10 | select { 11 | case c <- x: 12 | x, y = y, x+y 13 | case <-quit: 14 | fmt.Println("quit") 15 | return 16 | } 17 | } 18 | } 19 | 20 | func main() { 21 | c := make(chan int) 22 | quit := make(chan int) 23 | go func() { 24 | for i := 0; i < 10; i++ { 25 | fmt.Println(<-c) 26 | } 27 | quit <- 0 28 | }() 29 | fibonacci(c, quit) 30 | } 31 | -------------------------------------------------------------------------------- /eBook/03.0.md: -------------------------------------------------------------------------------- 1 | #3 Conocimientos básicos sobre la Web 2 | 3 | La razón por la que usted esta leyendo este libro, es porque esta buscando aprender a desarrollar aplicaciones web con Go. Como dije antes, Go nos provee muchos paquetes con un gran potencial como es el `http`. Este nos ayudará mucho cuando queramos desarrollar aplicaciones web. En los siguientes capítulos te voy a enseñar todo lo que necesita saber, en este capítulo vamos a hablar sobre algunos conceptos sobre la web y como correr aplicaciones web en Go. 4 | 5 | ## Enlaces 6 | 7 | - [Indice](preface.md) 8 | - Capítulo anterior: [Capitulo 2 Resumen](02.8.md) 9 | - Siguiente sección: [Principio para el trabajo en la Web](03.1.md) 10 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.3/basic_functions/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 2.3 from "Build Web Application with Golang" 2 | // Purpose: Creating a basic function 3 | package main 4 | 5 | import "fmt" 6 | 7 | // return greater value between a and b 8 | func max(a, b int) int { 9 | if a > b { 10 | return a 11 | } 12 | return b 13 | } 14 | 15 | func main() { 16 | x := 3 17 | y := 4 18 | z := 5 19 | 20 | max_xy := max(x, y) // call function max(x, y) 21 | max_xz := max(x, z) // call function max(x, z) 22 | 23 | fmt.Printf("max(%d, %d) = %d\n", x, y, max_xy) 24 | fmt.Printf("max(%d, %d) = %d\n", x, z, max_xz) 25 | fmt.Printf("max(%d, %d) = %d\n", y, z, max(y, z)) // call function here 26 | } 27 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.5/embedded_method/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | import "fmt" 3 | 4 | type Human struct { 5 | name string 6 | age int 7 | phone string 8 | } 9 | 10 | type Student struct { 11 | Human // anonymous field 12 | school string 13 | } 14 | 15 | type Employee struct { 16 | Human 17 | company string 18 | } 19 | 20 | // define a method in Human 21 | func (h *Human) SayHi() { 22 | fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone) 23 | } 24 | 25 | func main() { 26 | mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"} 27 | sam := Employee{Human{"Sam", 45, "111-888-XXXX"}, "Golang Inc"} 28 | 29 | mark.SayHi() 30 | sam.SayHi() 31 | } 32 | -------------------------------------------------------------------------------- /eBook/07.7.md: -------------------------------------------------------------------------------- 1 | # 7.7 Resumen 2 | 3 | En este capítulo, presentamos algunas herramientas de proceso de texto como XML, JSON, Regexp y plantilla. XML y JSON son herramientas de intercambio de datos, si se puede representar a casi todo tipo de información, aunque estos dos formatos. Regexp es una poderosa herramienta para buscar, reemplazar, cortar el contenido del texto. Con la plantilla, usted puede combinar fácilmente datos dinámicos con archivos estáticos. Estas herramientas son útiles cuando se desarrollan aplicaciones web, espero que entienda más sobre el procesamiento y la presentación de contenidos.. 4 | 5 | ## Links 6 | 7 | - [Directory](preface.md) 8 | - Previous section: [Strings](07.6.md) 9 | - Next chapter: [Web services](08.0.md) 10 | -------------------------------------------------------------------------------- /code/src/apps/ch.3.4/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 3.4 from "Build Web Application with Golang" 2 | // Purpose: Shows how to create a handler for `http.ListenAndServe()` 3 | // Run `go run main.go` then access `http://localhost:9090` 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "net/http" 9 | ) 10 | 11 | type MyMux struct { 12 | } 13 | 14 | func (p *MyMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { 15 | if r.URL.Path == "/" { 16 | sayhelloName(w, r) 17 | return 18 | } 19 | http.NotFound(w, r) 20 | return 21 | } 22 | 23 | func sayhelloName(w http.ResponseWriter, r *http.Request) { 24 | fmt.Fprintf(w, "Hello myroute!") 25 | } 26 | 27 | func main() { 28 | mux := &MyMux{} 29 | http.ListenAndServe(":9090", mux) 30 | } 31 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.4/embedded_structs_with_name_conflict/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 2.4 from "Build Web Application with Golang" 2 | // Purpose: Shows a name conflict with a embedded field 3 | package main 4 | 5 | import "fmt" 6 | 7 | type Human struct { 8 | name string 9 | age int 10 | phone string // Human has phone field 11 | } 12 | 13 | type Employee struct { 14 | Human // embedded field Human 15 | speciality string 16 | phone string // phone in employee 17 | } 18 | 19 | func main() { 20 | Bob := Employee{Human{"Bob", 34, "777-444-XXXX"}, "Designer", "333-222"} 21 | fmt.Println("Bob's work phone is:", Bob.phone) 22 | // access phone field in Human 23 | fmt.Println("Bob's personal phone is:", Bob.Human.phone) 24 | } 25 | -------------------------------------------------------------------------------- /eBook/04.6.md: -------------------------------------------------------------------------------- 1 | # 4.6 Resumen 2 | 3 | En este capítulo, hemos aprendido sobre todo la forma de procesar los datos del formulario en Ir a través de ejemplos acerca de registro de usuario y carga de archivos. También entendemos que verificar los datos de usuario es extremadamente importante para la seguridad del sitio web, y utilizamos una sección a hablar acerca de cómo filtrar los datos con la expresión regular. 4 | 5 | Espero que usted sabe más acerca de la comunicación entre el cliente y el lado servidor, que es cliente envía datos al servidor, y el servidor responde al cliente después de los datos procesados. 6 | 7 | ## Enlaces 8 | 9 | - [Indice](preface.md) 10 | - Sección anterior: [Subida de archivos](04.5.md) 11 | - Siguiente sección: [Base de datos](05.0.md) 12 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.3/panic_and_recover/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 2.3 from "Build Web Application with Golang" 2 | // Purpose: Showing how to use `panic()` and `recover()` 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | ) 9 | 10 | var user = os.Getenv("USER") 11 | 12 | func check_user() { 13 | if user == "" { 14 | panic("no value for $USER") 15 | } 16 | fmt.Println("Environment Variable `USER` =", user) 17 | } 18 | func throwsPanic(f func()) (b bool) { 19 | defer func() { 20 | if x := recover(); x != nil { 21 | fmt.Println("Panic message =", x); 22 | b = true 23 | } 24 | }() 25 | f() // if f causes panic, it will recover 26 | return 27 | } 28 | func main(){ 29 | didPanic := throwsPanic(check_user) 30 | fmt.Println("didPanic =", didPanic) 31 | } 32 | -------------------------------------------------------------------------------- /code/src/apps/ch.4.3/index.gtpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

Cross Site Scripting Attack Test

5 | {{if .}} 6 | Previous User Input:
7 | 8 |
{{.}}
9 | {{end}} 10 |
11 | 15 |
16 | 20 |
21 | 22 |
23 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.5/attach_methods_to_struct/main.go: -------------------------------------------------------------------------------- 1 | // Example code from Chapter 2.5 2 | // Attach method to struct. 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "math" 8 | ) 9 | 10 | type Rectangle struct { 11 | width, height float64 12 | } 13 | 14 | type Circle struct { 15 | radius float64 16 | } 17 | 18 | func (r Rectangle) area() float64 { 19 | return r.width * r.height 20 | } 21 | 22 | func (c Circle) area() float64 { 23 | return c.radius * c.radius * math.Pi 24 | } 25 | 26 | func main() { 27 | r1 := Rectangle{12, 2} 28 | r2 := Rectangle{9, 4} 29 | c1 := Circle{10} 30 | c2 := Circle{25} 31 | 32 | fmt.Println("Area of r1 is: ", r1.area()) 33 | fmt.Println("Area of r2 is: ", r2.area()) 34 | fmt.Println("Area of c1 is: ", c1.area()) 35 | fmt.Println("Area of c2 is: ", c2.area()) 36 | } 37 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.5/method_overload/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Human struct { 6 | name string 7 | age int 8 | phone string 9 | } 10 | 11 | type Student struct { 12 | Human 13 | school string 14 | } 15 | 16 | type Employee struct { 17 | Human 18 | company string 19 | } 20 | 21 | func (h *Human) SayHi() { 22 | fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone) 23 | } 24 | 25 | func (e *Employee) SayHi() { 26 | fmt.Printf("Hi, I am %s, I work at %s. Call me on %s\n", e.name, 27 | e.company, e.phone) //Yes you can split into 2 lines here. 28 | } 29 | 30 | func main() { 31 | mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"} 32 | sam := Employee{Human{"Sam", 45, "111-888-XXXX"}, "Golang Inc"} 33 | 34 | mark.SayHi() 35 | sam.SayHi() 36 | } 37 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.6/reflection/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | func show_interface_none() { 9 | fmt.Println("\nshow_interface_none()") 10 | var a interface{} 11 | a = "string" 12 | a = 1 13 | a = false 14 | fmt.Println("a =", a) 15 | } 16 | func show_reflection() { 17 | fmt.Println("\nshow_reflection()") 18 | var x float64 = 3.4 19 | v := reflect.ValueOf(x) 20 | fmt.Println("type:", v.Type()) 21 | fmt.Println("kind is float64:", v.Kind() == reflect.Float64) 22 | fmt.Println("value:", v.Float()) 23 | 24 | p := reflect.ValueOf(&x) 25 | newX := p.Elem() 26 | newX.SetFloat(7.1) 27 | fmt.Println("newX =", newX) 28 | fmt.Println("newX float64() value:", newX.Float()) 29 | } 30 | func main() { 31 | show_interface_none() 32 | show_reflection() 33 | } 34 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.3/pass_by_value_and_pointer/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 2.3 from "Build Web Application with Golang" 2 | // Purpose: Shows passing a variable by value and reference 3 | package main 4 | 5 | import "fmt" 6 | 7 | func add_by_value(a int) int { 8 | a = a + 1 9 | return a 10 | } 11 | func add_by_reference(a *int) int { 12 | *a = *a + 1 13 | return *a 14 | } 15 | func show_add_by_value() { 16 | x := 3 17 | fmt.Println("x = ", x) 18 | fmt.Println("add_by_value(x) =", add_by_value(x) ) 19 | fmt.Println("x = ", x) 20 | } 21 | func show_add_by_reference() { 22 | x := 3 23 | fmt.Println("x = ", x) 24 | // &x pass memory address of x 25 | fmt.Println("add_by_reference(&x) =", add_by_reference(&x) ) 26 | fmt.Println("x = ", x) 27 | } 28 | func main() { 29 | show_add_by_value() 30 | show_add_by_reference() 31 | } 32 | -------------------------------------------------------------------------------- /eBook/ref.md: -------------------------------------------------------------------------------- 1 | # Apéndice A Referencias 2 | 3 | Este libro es un resumen de mi experiencia con Go, algunos de los contenidos son de cualquiera de los sitios o blog de otros gophers. Muchas gracias a ellos! 4 | 5 | 1. [golang blog](http://blog.golang.org) 6 | 2. [Russ Cox blog](http://research.swtch.com/) 7 | 3. [go book](http://go-book.appsp0t.com/) 8 | 4. [golangtutorials](http://golangtutorials.blogspot.com) 9 | 5. [轩脉刃de刀光剑影](http://www.cnblogs.com/yjf512/) 10 | 6. [Go Programming Language](http://golang.org/doc/) 11 | 7. [Network programming with Go](http://jan.newmarch.name/go/) 12 | 8. [setup-the-rails-application-for-internationalization](http://guides.rubyonrails.org/i18n.html#setup-the-rails-application-for-internationalization) 13 | 9. [The Cross-Site Scripting (XSS) FAQ](http://www.cgisecurity.com/xss-faq.html) 14 | 15 | ## Enlaces 16 | 17 | - [Indice](preface.md) -------------------------------------------------------------------------------- /eBook/05.7.md: -------------------------------------------------------------------------------- 1 | # 5.7 Resumen 2 | 3 | En este capítulo, primero se aprendió el diseño de la interfaz `database/sql`, y muchos drivers de bases de datos de terceros para diferentes tipos de base de datos. Entonces le presenté beedb, un ORM para bases de datos relacionales, también se mostraron algunos ejemplos para el manejo de base de datos. Al final, he hablado de algunas bases de datos NoSQL, vimos que Go nos da muy buen soporte para las bases de datos NoSQL. 4 | 5 | Después de leer este capítulo, espero que sepa cómo operar bases de datos con Go. Esta es la parte más importante en el desarrollo web, así que quiero que entiendan completamente las ideas de el diseño de la interfaz `database/sql`. 6 | 7 | 8 | ## Enlaces 9 | 10 | - [Indice](preface.md) 11 | - Sección anterior: [Base de datos NoSQL](05.6.md) 12 | - Siguiente sección: [Almacenamiento de datos y sesiones](06.0.md) -------------------------------------------------------------------------------- /eBook/10.4.md: -------------------------------------------------------------------------------- 1 | # 10.4 Resumen 2 | 3 | A través de la introducción de este capítulo, el lector debe ser la forma de operar una idea de la i18n, también introdujo basándose en el contenido de este capítulo se implementa una solución de código abierto para el go-i18n: https://github.com/astaxie/ go-i18n través de esta biblioteca de código abierto que podemos lograr fácilmente la versión multi-idioma de la aplicación web, por lo que nuestras aplicaciones para lograr fácilmente la internacionalización. Si usted encuentra un error en esta biblioteca de código abierto o los lugares que faltan, por favor únase a este proyecto de código abierto, esforcémonos para convertirse bibliotecas estándar de la biblioteca de Go. 4 | 5 | ## Links 6 | 7 | - [Directory](preface.md) 8 | - Previous section: [International sites](10.3.md) 9 | - Next chapter: [Error handling, debugging and testing](11.0.md) 10 | -------------------------------------------------------------------------------- /eBook/06.5.md: -------------------------------------------------------------------------------- 1 | # 6.5 Resumen 2 | 3 | En este capítulo, hemos aprendido lo que es una sesión y lo que son las cookies, y la relación entre ellos. Y debido a que Go no admite sesiones en la biblioteca estándar, fue el motivo por el que se diseñó un gestor de sesiones, pasar por todo el proceso de crear la sesión y eliminar la sesión. Entonces definimos una interfaz llamada `Procider` que soporta todas las estructuras de almacenamiento de sesiones. En la sección 6.3, implementamos un gestor de sesiones que guardar los datos en memoria. En la sección 6.4, le enseñé a secuestrar la sesión y las formas de prevenir el secuestro de las sesiones. Espero que ahora conozca todos los principios de trabajo de la sesión con el fin de poder utilizar la sesión de manera segura. 4 | 5 | ## Enlaces 6 | 7 | - [Indice](preface.md) 8 | - Sección anterior: [Prevenir hijack de la sesión](06.4.md) 9 | - Siguiente sección: [Archivos de texto](07.0.md) -------------------------------------------------------------------------------- /eBook/01.5.md: -------------------------------------------------------------------------------- 1 | # 1.5 Resumen 2 | 3 | En este capitulo, hemos hablado sobre como instalar Go de tres formas diferentes, incluyendo como hacerlo desde el código fuente, el paquete estándar y herramientas de terceros. Luego mostramos como configurar nuestro entorno de desarrollo Go, principalmente hablamos sobre el `$GOPATH`. Después de eso, hicimos una introducción sobre los pasos para compilar y correr nuestro programas en Go. Entonces hablamos sobre algunos de los comando de Go, estos comandos incluyen compilar, instalar, dar formato, testear. Finalmente, mostramos algunas herramientas poderosas para desarrollar programas en Go, como LiteIDE, Sublime Text, Vim, Emacs, Eclipse, IntelliJ IDEA, etc. Usted puede elegir cualquiera de ellas para comenzar a explorar el mundo de Go. 4 | 5 | ## Enlaces 6 | 7 | - [Indice](preface.md) 8 | - Sección anterior: [Herramientas de desarrollo para Go](01.4.md) 9 | - Siguiente sección: [Conocimientos básicos sobre Go](02.0.md) 10 | -------------------------------------------------------------------------------- /code/src/apps/ch.3.2/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 3.2 from "Build Web Application with Golang" 2 | // Purpose: Shows how to acces the form values from the request 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "log" 8 | "net/http" 9 | "strings" 10 | ) 11 | 12 | func sayhelloName(w http.ResponseWriter, r *http.Request) { 13 | r.ParseForm() // parse arguments, you have to call this by yourself 14 | fmt.Println(r.Form) // print form information in server side 15 | fmt.Println("path", r.URL.Path) 16 | fmt.Println("scheme", r.URL.Scheme) 17 | fmt.Println(r.Form["url_long"]) 18 | for k, v := range r.Form { 19 | fmt.Println("key:", k) 20 | fmt.Println("val:", strings.Join(v, "")) 21 | } 22 | fmt.Fprintf(w, "Hello astaxie!") // send data to client side 23 | } 24 | 25 | func main() { 26 | http.HandleFunc("/", sayhelloName) // set router 27 | err := http.ListenAndServe(":9090", nil) // set listen port 28 | if err != nil { 29 | log.Fatal("ListenAndServe: ", err) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.6/switch_type_check/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | type Element interface{} 9 | type List []Element 10 | 11 | type Person struct { 12 | name string 13 | age int 14 | } 15 | 16 | func (p Person) String() string { 17 | return "(name: " + p.name + " - age: " + strconv.Itoa(p.age) + " years)" 18 | } 19 | 20 | func main() { 21 | list := make(List, 3) 22 | list[0] = 1 //an int 23 | list[1] = "Hello" //a string 24 | list[2] = Person{"Dennis", 70} 25 | 26 | for index, element := range list { 27 | switch value := element.(type) { 28 | case int: 29 | fmt.Printf("list[%d] is an int and its value is %d\n", index, value) 30 | case string: 31 | fmt.Printf("list[%d] is a string and its value is %s\n", index, value) 32 | case Person: 33 | fmt.Printf("list[%d] is a Person and its value is %s\n", index, value) 34 | default: 35 | fmt.Println("list[%d] is of a different type", index) 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /eBook/13.6.md: -------------------------------------------------------------------------------- 1 | # 13.6 Resumen 2 | 3 | En este capítulo se describe cómo implementar una base importante del marco lenguaje Go, que incluye el diseño de enrutamiento debido a la http Go paquete integrado de enrutamiento algunas deficiencias, hemos diseñado una regla de enrutamiento dinámico y, a continuación, se introduce el diseño del controlador patrón MVC , controlador implementa la aplicación REST, las ideas principales de la trama tornado, y luego diseñar y poner en práctica el diseño de la plantilla y la tecnología de renderizado automático, a través principalmente del Go motor incorporado de la plantilla, y finalmente introducir algunos registros auxiliares, configuración, etc diseño de la información, a través de estos diseños que implementó un beego marco básico, presenta el marco ha sido abierta en GitHub, finalmente beego implementó un sistema de blog, a través de un código detallado ejemplo demuestra cómo desarrollar rápidamente un sitio. 4 | 5 | ## Links 6 | 7 | - [Directory](preface.md) 8 | - Previous section: [Add, delete and update blogs](13.5.md) 9 | - Next chapter: [Develop web framework](14.0.md) 10 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.4/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 2.4 from "Build Web Application with Golang" 2 | // Purpose: Shows different ways of creating a struct 3 | package main 4 | 5 | import "fmt" 6 | 7 | func show_basic_struct() { 8 | fmt.Println("\nshow_basic_struct()") 9 | type person struct { 10 | name string 11 | age int 12 | } 13 | 14 | var P person // p is person type 15 | 16 | P.name = "Astaxie" // assign "Astaxie" to the filed 'name' of p 17 | P.age = 25 // assign 25 to field 'age' of p 18 | fmt.Printf("The person's name is %s\n", P.name) // access field 'name' of p 19 | 20 | tom := person{"Tom", 25} 21 | 22 | bob := person{age: 24, name: "Bob"} 23 | 24 | fmt.Printf("tom = %+v\n", tom) 25 | fmt.Printf("bob = %#v\n", bob) 26 | } 27 | func show_anonymous_struct() { 28 | fmt.Println("\nshow_anonymous_struct()") 29 | fmt.Printf("Anonymous struct = %#v\n", struct { 30 | name string 31 | count int 32 | }{ 33 | "counter", 1, 34 | }) 35 | } 36 | func main() { 37 | show_basic_struct() 38 | show_anonymous_struct() 39 | } 40 | -------------------------------------------------------------------------------- /code/src/apps/ch.4.5/client_upload/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io" 7 | "io/ioutil" 8 | "mime/multipart" 9 | "net/http" 10 | "os" 11 | ) 12 | 13 | func checkError(err error) { 14 | if err != nil { 15 | panic(err) 16 | } 17 | } 18 | func postFile(filename string, targetUrl string) { 19 | bodyBuf := &bytes.Buffer{} 20 | bodyWriter := multipart.NewWriter(bodyBuf) 21 | fileWriter, err := bodyWriter.CreateFormFile("uploadfile", filename) 22 | checkError(err) 23 | 24 | fh, err := os.Open(filename) 25 | checkError(err) 26 | 27 | _, err = io.Copy(fileWriter, fh) 28 | checkError(err) 29 | 30 | contentType := bodyWriter.FormDataContentType() 31 | bodyWriter.Close() 32 | resp, err := http.Post(targetUrl, contentType, bodyBuf) 33 | checkError(err) 34 | 35 | defer resp.Body.Close() 36 | resp_body, err := ioutil.ReadAll(resp.Body) 37 | checkError(err) 38 | 39 | fmt.Println(resp.Status) 40 | fmt.Println(string(resp_body)) 41 | } 42 | func main() { 43 | target_url := "http://localhost:9090/upload" 44 | filename := "../file.txt" 45 | postFile(filename, target_url) 46 | } 47 | -------------------------------------------------------------------------------- /eBook/02.0.md: -------------------------------------------------------------------------------- 1 | # 2 Conocimientos básicos sobre Go 2 | 3 | Go es un lenguaje de programación compilado, y pertenece a la familia de C. Sin embargo, su velocidad de compilación es muy superior a la de otros lenguajes de la familia de C. Tiene solo 25 palabras reservadas, incluso menos que las 26 letras Ingles! Vamos a echar un vistazo a estas palabras reservadas antes de comenzar. 4 | 5 | break default func interface select 6 | case defer go map struct 7 | chan else goto package switch 8 | const fallthrough if range type 9 | continue for import return var 10 | 11 | En este capitulo, voy a enseñarles algunos conocimientos básicos sobre Go. Usted va a ver lo conciso que es el lenguaje de programación Go, y lo hermoso del diseño del mismo. Programar con Go puede llegar a ser muy divertido. Después de finalizar este capitulo, va a estar familiarizado con estas palabras reservadas. 12 | 13 | ## Enlaces 14 | 15 | - [Indice](preface.md) 16 | - Sección anterior: [Resumen del Capitulo 1](01.5.md) 17 | - Siguiente sección: ["Hello, Go"](02.1.md) 18 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.6/type_check/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | type Element interface{} 9 | type List []Element 10 | 11 | type Person struct { 12 | name string 13 | age int 14 | } 15 | 16 | func (p Person) String() string { 17 | return "(name: " + p.name + " - age: " + strconv.Itoa(p.age) + " years)" 18 | } 19 | 20 | func main() { 21 | list := make(List, 3) 22 | list[0] = 1 // an int 23 | list[1] = "Hello" // a string 24 | list[2] = Person{"Dennis", 70} 25 | 26 | for index, element := range list { 27 | if value, ok := element.(int); ok { 28 | fmt.Printf("list[%d] is an int and its value is %d\n", index, value) 29 | } else if value, ok := element.(string); ok { 30 | fmt.Printf("list[%d] is a string and its value is %s\n", index, value) 31 | } else if value, ok := element.(Person); ok { 32 | fmt.Printf("list[%d] is a Person and its value is %s\n", index, value) 33 | } else { 34 | fmt.Println("list[%d] is of a different type", index) 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.3/type_function/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 2.3 from "Build Web Application with Golang" 2 | // Purpose: Shows how to define a function type 3 | package main 4 | 5 | import "fmt" 6 | 7 | type testInt func(int) bool // define a function type of variable 8 | 9 | func isOdd(integer int) bool { 10 | if integer%2 == 0 { 11 | return false 12 | } 13 | return true 14 | } 15 | 16 | func isEven(integer int) bool { 17 | if integer%2 == 0 { 18 | return true 19 | } 20 | return false 21 | } 22 | 23 | // pass the function `f` as an argument to another function 24 | 25 | func filter(slice []int, f testInt) []int { 26 | var result []int 27 | for _, value := range slice { 28 | if f(value) { 29 | result = append(result, value) 30 | } 31 | } 32 | return result 33 | } 34 | func init() { 35 | fmt.Println("\n#init() was called.") 36 | } 37 | func main() { 38 | slice := []int{1, 2, 3, 4, 5, 7} 39 | fmt.Println("slice = ", slice) 40 | odd := filter(slice, isOdd) // use function as values 41 | fmt.Println("Odd elements of slice are: ", odd) 42 | even := filter(slice, isEven) 43 | fmt.Println("Even elements of slice are: ", even) 44 | } 45 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.3/import_packages/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 2.3 from "Build Web Application with Golang" 2 | // Purpose: Shows different ways of importing a package. 3 | // Note: For the package `only_call_init`, we reference the path from the 4 | // base directory of `$GOPATH/src`. The reason being Golang discourage 5 | // the use of relative paths when import packages. 6 | // BAD: "./only_call_init" 7 | // GOOD: "apps/ch.2.3/import_packages/only_call_init" 8 | package main 9 | 10 | import ( 11 | // `_` will only call init() inside the package only_call_init 12 | _ "apps/ch.2.3/import_packages/only_call_init" 13 | f "fmt" // import the package as `f` 14 | . "math" // makes the public methods and constants global 15 | "mymath" // custom package located at $GOPATH/src/ 16 | "os" // normal import of a standard package 17 | "text/template" // the package takes the name of last folder path, `template` 18 | ) 19 | 20 | func main() { 21 | f.Println("mymath.Sqrt(4) =", mymath.Sqrt(4)) 22 | f.Println("E =", E) // references math.E 23 | 24 | t, _ := template.New("test").Parse("Pi^2 = {{.}}") 25 | t.Execute(os.Stdout, Pow(Pi, 2)) 26 | } 27 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.4/embedded_structs/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 2.4 from "Build Web Application with Golang" 2 | // Purpose: Example of embedded fields 3 | package main 4 | 5 | import "fmt" 6 | 7 | type Human struct { 8 | name string 9 | age int 10 | weight int 11 | } 12 | 13 | type Student struct { 14 | Human // anonymous field, it means Student struct includes all fields that Human has. 15 | speciality string 16 | } 17 | 18 | func main() { 19 | // initialize a student 20 | mark := Student{Human{"Mark", 25, 120}, "Computer Science"} 21 | 22 | // access fields 23 | fmt.Println("His name is ", mark.name) 24 | fmt.Println("His age is ", mark.age) 25 | fmt.Println("His weight is ", mark.weight) 26 | fmt.Println("His speciality is ", mark.speciality) 27 | // modify notes 28 | mark.speciality = "AI" 29 | fmt.Println("Mark changed his speciality") 30 | fmt.Println("His speciality is ", mark.speciality) 31 | // modify age 32 | fmt.Println("Mark become old") 33 | mark.age = 46 34 | fmt.Println("His age is", mark.age) 35 | // modify weight 36 | fmt.Println("Mark is not an athlete any more") 37 | mark.weight += 60 38 | fmt.Println("His weight is", mark.weight) 39 | } 40 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.4/embedded_structs2/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 2.4 from "Build Web Application with Golang" 2 | // Purpose: Another example of embedded fields 3 | package main 4 | 5 | import "fmt" 6 | 7 | type Skills []string 8 | 9 | type Human struct { 10 | name string 11 | age int 12 | weight int 13 | } 14 | 15 | type Student struct { 16 | Human // struct as embedded field 17 | Skills // string slice as embedded field 18 | int // built-in type as embedded field 19 | speciality string 20 | } 21 | 22 | func main() { 23 | // initialize Student Jane 24 | jane := Student{Human: Human{"Jane", 35, 100}, speciality: "Biology"} 25 | // access fields 26 | fmt.Println("Her name is ", jane.name) 27 | fmt.Println("Her age is ", jane.age) 28 | fmt.Println("Her weight is ", jane.weight) 29 | fmt.Println("Her speciality is ", jane.speciality) 30 | // modify value of skill field 31 | jane.Skills = []string{"anatomy"} 32 | fmt.Println("Her skills are ", jane.Skills) 33 | fmt.Println("She acquired two new ones ") 34 | jane.Skills = append(jane.Skills, "physics", "golang") 35 | fmt.Println("Her skills now are ", jane.Skills) 36 | // modify embedded field 37 | jane.int = 3 38 | fmt.Println("Her preferred number is", jane.int) 39 | } 40 | -------------------------------------------------------------------------------- /eBook/11.4.md: -------------------------------------------------------------------------------- 1 | # 11.4 Resumen 2 | En este capítulo nos presentaron a través de tres subsecciones Ir idioma cómo controlar los errores, cómo diseñar un control de errores, y luego una segunda sección se describe cómo BGF depurador GDB podemos de un solo paso a través del depurador, puede ver las variables, modificar las variables, proceso de aplicación de impresión, etc Por último, se describe cómo utilizar el lenguaje Go viene con un marco ligero prueba a escribir pruebas unitarias y pruebas de estrés, el uso de la prueba de marcha se puede realizar fácilmente estas pruebas nos permiten en el futuro para modificar el código después de actualizar muy conveniente para las pruebas de regresión. Quizás por este capítulo se escribe la lógica de aplicación sin ningún tipo de ayuda, pero para que usted escriba el código del programa es esencial para mantener una alta calidad, ya que una aplicación web bien debe tener un buen mecanismo de manejo de errores (error de amable, escalabilidad), hay una buena prueba de la unidad y de la prueba de esfuerzo para asegurar en línea después de que el código es capaz de mantener un buen rendimiento y se ejecuta como se esperaba. 3 | 4 | ## Links 5 | 6 | - [Directory](preface.md) 7 | - Previous section: [Write test cases](11.3.md) 8 | - Next chapter: [Deployment and maintenance](12.0.md) 9 | -------------------------------------------------------------------------------- /code/src/apps/ch.4.3/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 4.3 from "Build Web Application with Golang" 2 | // Purpose: Shows how to properly escape input 3 | package main 4 | 5 | import ( 6 | "html/template" 7 | "net/http" 8 | textTemplate "text/template" 9 | ) 10 | 11 | var t *template.Template = template.Must(template.ParseFiles("index.gtpl")) 12 | 13 | func index(w http.ResponseWriter, r *http.Request) { 14 | r.ParseForm() 15 | userInput := r.Form.Get("userinput") 16 | if 0 < len(r.Form.Get("escape")) { 17 | t.Execute(w, template.HTMLEscapeString(userInput)) 18 | } else { 19 | // Variables with type `template.HTML` are not escaped when passed to `.Execute()` 20 | t.Execute(w, template.HTML(userInput)) 21 | } 22 | } 23 | func templateHandler(w http.ResponseWriter, r *http.Request) { 24 | r.ParseForm() 25 | userInput := r.Form.Get("userinput") 26 | if 0 < len(r.Form.Get("escape")) { 27 | // `html/template.Execute()` escapes input 28 | t.Execute(w, userInput) 29 | } else { 30 | tt := textTemplate.Must(textTemplate.ParseFiles("index.gtpl")) 31 | // `text/template.Execute()` doesn't escape input 32 | tt.Execute(w, userInput) 33 | } 34 | } 35 | func main() { 36 | http.HandleFunc("/", index) 37 | http.HandleFunc("/template", templateHandler) 38 | http.ListenAndServe(":9090", nil) 39 | } 40 | -------------------------------------------------------------------------------- /eBook/08.5.md: -------------------------------------------------------------------------------- 1 | # 8.5 Resumen 2 | 3 | En este capítulo, se lo presenté a varios modelos de la corriente principal de desarrollo de aplicaciones web. En la sección 8.1, describí la programación básica de redes: la programación del zócalo. Debido a que la dirección de la red que es una rápida evolución, y el Zócalo es la piedra angular del conocimiento de esta evolución, debe estar dominado como desarrollador. En la sección 8.2, describí HTML5 WebSocket, la función cada vez más popular, el servidor puede empujar mensajes a través de él, simplificado el modo de sondeo de AJAX. En la sección 8.3, implementamos una aplicación REST simple, que es especialmente adecuado para el desarrollo de las API de red; debido al rápido desarrollo de las aplicaciones móviles, creo que va a ser una tendencia. En la sección 8.4, aprendimos sobre Go RPC. 4 | 5 | Go proporciona un buen soporte por encima de los cuatro tipos de métodos de desarrollo. Tenga en cuenta que el paquete net y sus sub-paquetes es el lugar donde las herramientas de programación de la red de Go son. Si desea más comprensión en profundidad de los detalles de implementación pertinentes, usted debe tratar de leer el código fuente de los paquetes. 6 | 7 | - [Directory](preface.md) 8 | - Previous section: [RPC](08.4.md) 9 | - Next chapter: [Security and encryption](09.0.md) 10 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.4/compare_age/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 2.4 from "Build Web Application with Golang" 2 | // Purpose: Shows you how to pass and use structs. 3 | package main 4 | 5 | import "fmt" 6 | 7 | // define a new type 8 | type person struct { 9 | name string 10 | age int 11 | } 12 | 13 | // compare age of two people, return the older person and differences of age 14 | // struct is passed by value 15 | func Older(p1, p2 person) (person, int) { 16 | if p1.age > p2.age { 17 | return p1, p1.age - p2.age 18 | } 19 | return p2, p2.age - p1.age 20 | } 21 | 22 | func main() { 23 | var tom person 24 | 25 | // initialization 26 | tom.name, tom.age = "Tom", 18 27 | 28 | // initialize two values by format "field:value" 29 | bob := person{age: 25, name: "Bob"} 30 | 31 | // initialize two values with order 32 | paul := person{"Paul", 43} 33 | 34 | tb_Older, tb_diff := Older(tom, bob) 35 | tp_Older, tp_diff := Older(tom, paul) 36 | bp_Older, bp_diff := Older(bob, paul) 37 | 38 | fmt.Printf("Of %s and %s, %s is older by %d years\n", tom.name, bob.name, tb_Older.name, tb_diff) 39 | 40 | fmt.Printf("Of %s and %s, %s is older by %d years\n", tom.name, paul.name, tp_Older.name, tp_diff) 41 | 42 | fmt.Printf("Of %s and %s, %s is older by %d years\n", bob.name, paul.name, bp_Older.name, bp_diff) 43 | } 44 | -------------------------------------------------------------------------------- /code/src/apps/ch.5.6/mongodb/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 5.6 from "Build Web Application with Golang" 2 | // Purpose: Shows you have to perform basic CRUD operations for a mongodb driver. 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "labix.org/v2/mgo" 8 | "labix.org/v2/mgo/bson" 9 | ) 10 | 11 | type Person struct { 12 | Name string 13 | Phone string 14 | } 15 | 16 | func checkError(err error) { 17 | if err != nil { 18 | panic(err) 19 | } 20 | } 21 | 22 | const ( 23 | DB_NAME = "test" 24 | DB_COLLECTION = "people" 25 | ) 26 | 27 | func main() { 28 | session, err := mgo.Dial("localhost") 29 | checkError(err) 30 | defer session.Close() 31 | 32 | session.SetMode(mgo.Monotonic, true) 33 | 34 | c := session.DB(DB_NAME).C(DB_COLLECTION) 35 | err = c.DropCollection() 36 | checkError(err) 37 | 38 | ale := Person{"Ale", "555-5555"} 39 | cla := Person{"Cla", "555-1234"} 40 | 41 | fmt.Println("Inserting") 42 | err = c.Insert(&ale, &cla) 43 | checkError(err) 44 | 45 | fmt.Println("Updating") 46 | ale.Phone = "555-0101" 47 | err = c.Update(bson.M{"name": "Ale"}, &ale) 48 | 49 | fmt.Println("Querying") 50 | result := Person{} 51 | err = c.Find(bson.M{"name": "Ale"}).One(&result) 52 | checkError(err) 53 | fmt.Println("Phone:", result.Phone) 54 | 55 | fmt.Println("Deleting") 56 | err = c.Remove(bson.M{"name": "Ale"}) 57 | checkError(err) 58 | } 59 | -------------------------------------------------------------------------------- /eBook/09.7.md: -------------------------------------------------------------------------------- 1 | # 9.7 Resumen 2 | 3 | En este capítulo se describe como: ataques CSRF, ataques XSS, ataques de inyección SQL, etc Algunas aplicaciones Web métodos típicos de ataque, que se deben a la aplicación en el filtro de entrada del usuario no causan buena, por lo que además de introducir el método de ataque en Además, también hemos introducido la forma de llevar a cabo con eficacia el filtrado de datos para evitar que estos ataques ocurran. A continuación, la contraseña para el derrame grave días iso, introducido en el diseño de aplicaciones Web se puede utilizar desde el básico al sistema de cifrado de expertos. Finalmente el cifrado y descifrado de datos sensibles breve, Go lenguaje proporciona tres algoritmos de cifrado simétrico: base64, AES y DES de implementación. 4 | 5 | El propósito de escribir este capítulo es para mejorar al lector en el concepto de seguridad en la conciencia interior, cuando la aplicación Web en la preparación de un poco más de cuidado, por lo que podemos escribir aplicaciones Web fuera de ataques de hackers. Ir lenguaje ha estado en el apoyo de un gran conjunto de herramientas anti-ataque, podemos sacar el máximo provecho de estos paquetes para hacer una aplicaciones Web seguras. 6 | 7 | ## Links 8 | 9 | - [Directory](preface.md) 10 | - Previous section: [Encrypt and decrypt data](09.6.md) 11 | - Next chapter: [Internationalization and localization](10.0.md) 12 | -------------------------------------------------------------------------------- /eBook/05.0.md: -------------------------------------------------------------------------------- 1 | # 5 Bases de Datos 2 | Para los desarrolladores web, la base de datos es el núcleo de desarrollo web. Puede guardar casi cualquier cosa en los datos de base de datos, consulta y actualización, al igual que la información del usuario, los productos o la lista de noticias. 3 | 4 | Go no tiene ningún controlador driver para la base de datos, pero tiene una interfaz de controlador se define en el paquete de base de `database/sql` , las personas pueden desarrollar controladores de base de datos basado en la interfaz. En la sección 5.1, vamos a hablar sobre el diseño de interfaz de controlador de base de datos en Go; en las secciones 05.02 a 05.04, voy a presentar algunos de los controladores de base de datos SQL a usted; en la sección 5.5, mostraré el ORM que he desarrollado que se basa en `database/sql` interfaz estandar, es compatible con la mayoría de los conductores que han implementado `database/sql` interfaz, y facilita el acceso a la base de datos de código de estilo Go. 5 | 6 | NoSQL es un tema candente en los últimos años, más sitios web deciden utilizar la base de datos NoSQL como su principal base de datos en lugar de sólo para uso de la caché. Voy a presentar dos bases de datos NoSQL que son MongoDB y Redis a usted en la sección 5.6. 7 | 8 | ## Enlaces 9 | 10 | - [Indice](preface.md) 11 | - Sección anterior: [Resumen](04.6.md) 12 | - Siguiente sección: [database/sql interfaz](05.1.md) -------------------------------------------------------------------------------- /eBook/06.0.md: -------------------------------------------------------------------------------- 1 | # 6 Almacenamiento de datos y la sesión 2 | 3 | Un tema importante en el desarrollo web es proporcionar una buena experiencia de usuario, pero HTTP es un protocolo sin estado, ¿cómo podemos controlar todo el proceso de visualización de los sitios web de los usuarios? Las soluciones clásicas utilizan cookies y sesiones, donde las cookies son el mecanismo del lado del cliente y la sesión se guarda en el servidor con el identificador único para cada usuario. Tomo nota de que la sesión se puede pasar en la URL o en la cookie, o incluso en su base de datos, que es mucho más seguro, pero puede arrastrar hacia abajo el rendimiento de su aplicación. 4 | 5 | En la sección 6.1, vamos a hablar de las diferencias entre cookies y sesión. En la sección 6.2, usted aprenderá cómo utilizar la sesiones en Go con una aplicación para gestionar sesiones. En la sección 6.3, vamos a hablar del secuestro de sesiónes y cómo prevenirlo cuando se sabe que la sesión se puede guardar en cualquier lugar. El gestor de sesiones lo vamos a implementar en la sección 6.3 salvando la sesión en memoria, pero si tenemos que ampliar nuestra aplicación vamos a tener el requisito de compartir la sesion, donde será mejor guardar la sesión en la base de datos, y hablaremos más sobre esto en la sección 6.4 . 6 | 7 | ## Enlaces 8 | 9 | - [Indice](preface.md) 10 | - Sección anterior: [Resumen](05.7.md) 11 | - Siguiente sección: [Sesiones y cookies](06.1.md) -------------------------------------------------------------------------------- /eBook/12.5.md: -------------------------------------------------------------------------------- 1 | # 12.5 Resumen 2 | En este capítulo se explica cómo implementar y mantener aplicaciones web se desarrollan diversos temas relacionados. El contenido es muy importante ser capaz de crear un mínimo de mantenimiento de aplicaciones basadas funcionando sin problemas, debemos tener en cuenta estas cuestiones. 3 | 4 | En concreto, la discusión en este capítulo incluyen: 5 | 6 | - Crear un sistema de registro robusto que puede registrar un error en caso de problemas y notificar al administrador del sistema 7 | - Manejar los errores de ejecución que pueden ocurrir, incluyendo la tala y la forma de mostrar al sistema fácil de usar que hay un problema 8 | - Manejo de errores 404, que indica al usuario no puede encontrar la página solicitada 9 | - Implementar aplicaciones en un entorno de producción (incluyendo cómo implementar las actualizaciones) 10 | - Cómo implementar aplicaciones de alta disponibilidad 11 | - Archivos y bases de datos de copia de seguridad y restauración 12 | 13 | Después de leer este capítulo, para el desarrollo de una aplicación web desde cero, estas cuestiones deben tenerse en cuenta, ya debe tener una comprensión global. Este capítulo le ayudará en la gestión actual entorno en el capítulo anterior describe el desarrollo del código. 14 | 15 | ## Links 16 | 17 | - [Directory](preface.md) 18 | - Previous section: [Backup and recovery](12.4.md) 19 | - Next chapter: [Build a web framework](13.0.md) 20 | -------------------------------------------------------------------------------- /eBook/07.0.md: -------------------------------------------------------------------------------- 1 | # 7 Archivos de texto 2 | 3 | El manejo de archivo de texto es una parte importante del desarrollo web, a menudo necesitamos producir o manejar el contenido de texto recibidos, incluyendo palabras, números, JSON, XML, etc. Como un lenguaje de alto rendimiento, Go tiene un buen soporte de la biblioteca estándar, y usted puede hacer su diseño más que impresionante, se puede utilizar fácilmente para hacer frente a su contenido de texto. Este capítulo contiene 4 secciones, lo que da la plena introducción del tratamiento de textos en Go. 4 | 5 | XML es un lenguaje interactivo que se usan comúnmente en muchas API, muchos servidores web que se escriben en Java están utilizando XML como lenguaje de interacción estándar, vamos a hablar de XML en la sección 7.1. En la sección 7.2, vamos a echar un vistazo a JSON, que es muy popular en los últimos años y mucho más conveniente que el XML. En la sección 7.3, vamos a hablar de las expresiones regulares que se parece a un lenguaje que es utilizado por aliens. En la sección 7.4, verá cómo utilizar el modelo MVC para desarrollar de aplicaciones en Go y el uso del paquete `template` para usar plantillas. En la sección 7.5, le daremos una introducción a el manejo de archivos y carpetas. Por último, vamos a explicar algunas de las operaciones de cadena en Go en la sección 7.6. 6 | 7 | ## Enlaces 8 | 9 | - [Indice](preface.md) 10 | - Sección anterior: [Resumen](06.5.md) 11 | - Siguiente sección: [XML](07.1.md) -------------------------------------------------------------------------------- /eBook/12.0.md: -------------------------------------------------------------------------------- 1 | # 12 Despliegue y mantenimiento 2 | Hasta el momento, ya hemos descrito la forma de desarrollar programas, depurador, y los procedimientos de prueba, como se suele decir: el desarrollo de la última del 10% al 90% de las veces, por lo que este capítulo se hará hincapié en esta última parte del 10% para llegar a ser verdaderamente la más confiable y utilizada por la aplicación excepcional, debe tener en cuenta algunos de los detalles de la mencionada 10% se refiere a estos pequeños detalles. 3 | 4 | En este capítulo vamos a ser cuatro secciones para introducir estos pequeños detalles del acuerdo, la primera sección se describe cómo programar los servicios de producción registrados en el registro, la forma de registro, se produce un error de un segundo apartado se describe cómo lidiar con nuestro programa, cómo de garantizar en la medida de lo posible un menor impacto al acceso del usuario a, y la tercera sección se describe cómo implementar Go programa independiente, debido a los actuales programas de Go que no se pueden escribir como daemon C, entonces el proceso de cómo manejamos el programa funcionando en segundo plano por lo que? La cuarta sección describe la aplicación de copia de seguridad y recuperación de datos, trate de asegurarse de que las aplicaciones se cuelgan puede mantener la integridad de los datos. 5 | 6 | ## Links 7 | 8 | - [Directory](preface.md) 9 | - Previous chapter: [Chapter 11 summary](11.4.md) 10 | - Next section: [Logs](12.1.md) 11 | -------------------------------------------------------------------------------- /code/src/apps/ch.5.6/redis/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 5.6 from "Build Web Application with Golang" 2 | // Purpose: Shows you have to perform basic CRUD operations for a redis driver. 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "github.com/astaxie/goredis" 8 | ) 9 | 10 | func checkError(err error) { 11 | if err != nil { 12 | panic(err) 13 | } 14 | } 15 | 16 | const ( 17 | DB_PORT = "9191" 18 | DB_URL = "127.0.0.1" 19 | ) 20 | 21 | func main() { 22 | var client goredis.Client 23 | 24 | // Set the default port in Redis 25 | client.Addr = DB_URL + ":" + DB_PORT 26 | 27 | // string manipulation 28 | fmt.Println("Inserting") 29 | err := client.Set("a", []byte("hello")) 30 | checkError(err) 31 | 32 | // list operation 33 | vals := []string{"a", "b", "c", "d"} 34 | for _, v := range vals { 35 | err = client.Rpush("l", []byte(v)) 36 | checkError(err) 37 | } 38 | fmt.Println("Updating") 39 | err = client.Set("a", []byte("a is for apple")) 40 | checkError(err) 41 | err = client.Rpush("l", []byte("e")) 42 | checkError(err) 43 | 44 | fmt.Println("Querying") 45 | val, err := client.Get("a") 46 | checkError(err) 47 | fmt.Println(string(val)) 48 | 49 | dbvals, err := client.Lrange("l", 0, 4) 50 | checkError(err) 51 | for i, v := range dbvals { 52 | println(i, ":", string(v)) 53 | } 54 | 55 | fmt.Println("Deleting") 56 | _, err = client.Del("l") 57 | checkError(err) 58 | _, err = client.Del("a") 59 | checkError(err) 60 | } 61 | -------------------------------------------------------------------------------- /eBook/02.8.md: -------------------------------------------------------------------------------- 1 | # 2.8 Resumen 2 | 3 | En este capitulo principalmente introducimos 25 palabras reservadas de Go. Vamos a repasar cuales son y que hacen. 4 | 5 | break default func interface select 6 | case defer go map struct 7 | chan else goto package switch 8 | const fallthrough if range type 9 | continue for import return var 10 | 11 | - `var` y `const` son usadas para definir variables y constantes. 12 | - `package` e `import` son para el uso de paquetes. 13 | - `func` es usada para definir funciones y métodos. 14 | - `return` es usada para devolver valores en funciones o métodos. 15 | - `defer` es usada para definir funciones defer. 16 | - `go` es usada para comenzar a correr una nueva goroutine. 17 | - `select` es usada para elegir entre múltiples canales de comunicación. 18 | - `interface` es usada para definir una interfaz. 19 | - `struct` es usada para definir tipos especiales personalizados. 20 | - `break`, `case`, `continue`, `for`, `fallthrough`, `else`, `if`, `switch`, `goto`, `default` fueron introducidos en la sección 2.3. 21 | - `chan` es usada para crear tipos de canales para comunicarse con las goroutines. 22 | - `type` es usada para definir tipos personalizados. 23 | - `map` es usada para definir un map que es como una tabla hash en otros lenguajes. 24 | - `range` es usada para leer datos desde un `slice`, `map` o `channel`. 25 | 26 | Si entendes como usar estas 25 palabras reservadas, usted ya a aprendido mucho sobre Go. 27 | 28 | ## Enlaces 29 | 30 | - [Indices](preface.md) 31 | - Sección anterior: [Concurrencia](02.7.md) 32 | - Siguiente sección: [Conocimientos básicos sobre la Web](03.0.md) -------------------------------------------------------------------------------- /code/src/apps/ch.4.1/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 4.1 from "Build Web Application with Golang" 2 | // Purpose: Shows how to create a simple login using a template 3 | // Run: `go run main.go`, then access `http://localhost:9090` and `http://localhost:9090/login` 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "html/template" 9 | "log" 10 | "net/http" 11 | "strings" 12 | ) 13 | 14 | func sayhelloName(w http.ResponseWriter, r *http.Request) { 15 | r.ParseForm() //Parse url parameters passed, then parse the response packet for the POST body (request body) 16 | // attention: If you do not call ParseForm method, the following data can not be obtained form 17 | fmt.Println(r.Form) // print information on server side. 18 | fmt.Println("path", r.URL.Path) 19 | fmt.Println("scheme", r.URL.Scheme) 20 | fmt.Println(r.Form["url_long"]) 21 | for k, v := range r.Form { 22 | fmt.Println("key:", k) 23 | fmt.Println("val:", strings.Join(v, "")) 24 | } 25 | fmt.Fprintf(w, "Hello astaxie!") // write data to response 26 | } 27 | 28 | func login(w http.ResponseWriter, r *http.Request) { 29 | fmt.Println("method:", r.Method) //get request method 30 | if r.Method == "GET" { 31 | t, _ := template.ParseFiles("login.gtpl") 32 | t.Execute(w, nil) 33 | } else { 34 | r.ParseForm() 35 | // logic part of log in 36 | fmt.Println("username:", r.Form["username"]) 37 | fmt.Println("password:", r.Form["password"]) 38 | } 39 | } 40 | 41 | func main() { 42 | http.HandleFunc("/", sayhelloName) // setting router rule 43 | http.HandleFunc("/login", login) 44 | err := http.ListenAndServe(":9090", nil) // setting listening port 45 | if err != nil { 46 | log.Fatal("ListenAndServe: ", err) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /eBook/01.0.md: -------------------------------------------------------------------------------- 1 | # 1 Configuración del entorno de desarrollo en Go 2 | 3 | Bienvenido al mundo de Go, vamos a comenzar a explorarlo! 4 | 5 | Go tiene una compilación muy rápida, recolector de basura, y el lenguaje tiene un sistema orientado a la concurrencia. Esto tiene las siguiente ventajas: 6 | 7 | - Compila grandes proyectos en solo unos pocos segundos. 8 | - Nos provee un modelo de desarrollo de software sobre el cual es sencillo razonar, evitando la mayor parte de los problemas causados por los archivos de cabecera del estilo de C. 9 | - Es un lenguaje estático que no tiene niveles en su sistema de tipos, por lo cual los usuarios no deberán pasar demasiado tiempo estudiando las relaciones entre tipos. Es mas un lenguaje orientado a objetos livianos. 10 | - Realiza la recolección de basura. Proporciona un soporte básico para la concurrencia y la comunicación. 11 | - Esta diseñado para equipos de mas de un núcleo. 12 | 13 | Go es un lenguaje compilado. Combina la eficiencia de los lenguajes interpretados o dinámicos con la seguridad de los lenguajes estáticos. Va a ser el lenguaje de elección para las computadoras de varios núcleos conectadas a la red. Por estos motivos, hay algunos problemas que tienen que resolver el propio lenguaje, como un rico sistema expresivo ligero de tipos, concurrencia y la recolección de basura estrictamente regulada. Desde hace algún tiempo, no han salido paquetes o herramientas que resuelvan estos problemas de manera pragmática, por esto nació la motivación para el lenguaje Go. 14 | 15 | En este capitulo, te voy a mostrar como realizar la instalación y configuración tu entorno de desarrollo Go. 16 | 17 | ## Links 18 | 19 | - [Indice](preface.md) 20 | - Siguiente sección: [Instalación](01.1.md) 21 | -------------------------------------------------------------------------------- /code/src/apps/ch.4.4/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 3.2 from "Build Web Application with Golang" 2 | // Purpose: Shows how to prevent duplicate submissions by using tokens 3 | // Example code for Chapter 4.4 based off the code from Chapter 4.2 4 | // Run `go run main.go` then access http://localhost:9090 5 | package main 6 | 7 | import ( 8 | "apps/ch.4.4/nonce" 9 | "apps/ch.4.4/validator" 10 | "html/template" 11 | "log" 12 | "net/http" 13 | ) 14 | 15 | const ( 16 | PORT = "9090" 17 | HOST_URL = "http://localhost:" + PORT 18 | ) 19 | 20 | var submissions nonce.Nonces 21 | var t *template.Template 22 | 23 | func index(w http.ResponseWriter, r *http.Request) { 24 | http.Redirect(w, r, HOST_URL+"/profile", http.StatusTemporaryRedirect) 25 | } 26 | func profileHandler(w http.ResponseWriter, r *http.Request) { 27 | t.ExecuteTemplate(w, "profile", submissions.NewNonce()) 28 | } 29 | func checkProfile(w http.ResponseWriter, r *http.Request) { 30 | var errs validator.Errors 31 | r.ParseForm() 32 | token := r.Form.Get("token") 33 | if err := submissions.CheckThenMarkToken(token); err != nil { 34 | errs = validator.Errors{[]error{err}} 35 | } else { 36 | p := validator.ProfilePage{&r.Form} 37 | errs = p.GetErrors() 38 | } 39 | t.ExecuteTemplate(w, "submission", errs) 40 | } 41 | func init() { 42 | submissions = nonce.New() 43 | t = template.Must(template.ParseFiles("profile.gtpl", "submission.gtpl")) 44 | } 45 | func main() { 46 | http.HandleFunc("/", index) 47 | http.HandleFunc("/profile", profileHandler) 48 | http.HandleFunc("/checkprofile", checkProfile) 49 | 50 | err := http.ListenAndServe(":"+PORT, nil) // setting listening port 51 | if err != nil { 52 | log.Fatal("ListenAndServe: ", err) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /code/src/apps/ch.4.4/nonce/main.go: -------------------------------------------------------------------------------- 1 | // A nonce is a number or string used only once. 2 | // This is useful for generating a unique token for login pages to prevent duplicate submissions. 3 | package nonce 4 | 5 | import ( 6 | "crypto/md5" 7 | "errors" 8 | "fmt" 9 | "io" 10 | "math/rand" 11 | "strconv" 12 | "time" 13 | ) 14 | 15 | // Contains a unique token 16 | type Nonce struct { 17 | Token string 18 | } 19 | 20 | // Keeps track of marked/used tokens 21 | type Nonces struct { 22 | hashs map[string]bool 23 | } 24 | 25 | func New() Nonces { 26 | return Nonces{make(map[string]bool)} 27 | } 28 | func (n *Nonces) NewNonce() Nonce { 29 | return Nonce{n.NewToken()} 30 | } 31 | 32 | // Returns a new unique token 33 | func (n *Nonces) NewToken() string { 34 | t := createToken() 35 | for n.HasToken(t) { 36 | t = createToken() 37 | } 38 | return t 39 | } 40 | 41 | // Checks if token has been marked. 42 | func (n *Nonces) HasToken(token string) bool { 43 | return n.hashs[token] == true 44 | } 45 | func (n *Nonces) MarkToken(token string) { 46 | n.hashs[token] = true 47 | } 48 | func (n *Nonces) CheckToken(token string) error { 49 | if token == "" { 50 | return errors.New("No token supplied") 51 | } 52 | if n.HasToken(token) { 53 | return errors.New("Duplicate submission.") 54 | } 55 | return nil 56 | } 57 | func (n *Nonces) CheckThenMarkToken(token string) error { 58 | defer n.MarkToken(token) 59 | if err := n.CheckToken(token); err != nil { 60 | return err 61 | } 62 | return nil 63 | } 64 | func createToken() string { 65 | h := md5.New() 66 | now := time.Now().Unix() 67 | io.WriteString(h, strconv.FormatInt(now, 10)) 68 | io.WriteString(h, strconv.FormatInt(rand.Int63(), 10)) 69 | return fmt.Sprintf("%x", h.Sum(nil)) 70 | } 71 | -------------------------------------------------------------------------------- /code/src/apps/ch.4.5/nonce/main.go: -------------------------------------------------------------------------------- 1 | // A nonce is a number or string used only once. 2 | // This is useful for generating a unique token for login pages to prevent duplicate submissions. 3 | package nonce 4 | 5 | import ( 6 | "crypto/md5" 7 | "errors" 8 | "fmt" 9 | "io" 10 | "math/rand" 11 | "strconv" 12 | "time" 13 | ) 14 | 15 | // Contains a unique token 16 | type Nonce struct { 17 | Token string 18 | } 19 | 20 | // Keeps track of marked/used tokens 21 | type Nonces struct { 22 | hashs map[string]bool 23 | } 24 | 25 | func New() Nonces { 26 | return Nonces{make(map[string]bool)} 27 | } 28 | func (n *Nonces) NewNonce() Nonce { 29 | return Nonce{n.NewToken()} 30 | } 31 | 32 | // Returns a new unique token 33 | func (n *Nonces) NewToken() string { 34 | t := createToken() 35 | for n.HasToken(t) { 36 | t = createToken() 37 | } 38 | return t 39 | } 40 | 41 | // Checks if token has been marked. 42 | func (n *Nonces) HasToken(token string) bool { 43 | return n.hashs[token] == true 44 | } 45 | func (n *Nonces) MarkToken(token string) { 46 | n.hashs[token] = true 47 | } 48 | func (n *Nonces) CheckToken(token string) error { 49 | if token == "" { 50 | return errors.New("No token supplied") 51 | } 52 | if n.HasToken(token) { 53 | return errors.New("Duplicate submission.") 54 | } 55 | return nil 56 | } 57 | func (n *Nonces) CheckThenMarkToken(token string) error { 58 | defer n.MarkToken(token) 59 | if err := n.CheckToken(token); err != nil { 60 | return err 61 | } 62 | return nil 63 | } 64 | func createToken() string { 65 | h := md5.New() 66 | now := time.Now().Unix() 67 | io.WriteString(h, strconv.FormatInt(now, 10)) 68 | io.WriteString(h, strconv.FormatInt(rand.Int63(), 10)) 69 | return fmt.Sprintf("%x", h.Sum(nil)) 70 | } 71 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.5/box_example/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | const ( 6 | WHITE = iota 7 | BLACK 8 | BLUE 9 | RED 10 | YELLOW 11 | ) 12 | 13 | type Color byte 14 | 15 | type Box struct { 16 | width, height, depth float64 17 | color Color 18 | } 19 | 20 | type BoxList []Box //a slice of boxes 21 | 22 | func (b Box) Volume() float64 { 23 | return b.width * b.height * b.depth 24 | } 25 | 26 | func (b *Box) SetColor(c Color) { 27 | b.color = c 28 | } 29 | 30 | func (bl BoxList) BiggestsColor() Color { 31 | v := 0.00 32 | k := Color(WHITE) 33 | for _, b := range bl { 34 | if b.Volume() > v { 35 | v = b.Volume() 36 | k = b.color 37 | } 38 | } 39 | return k 40 | } 41 | 42 | func (bl BoxList) PaintItBlack() { 43 | for i, _ := range bl { 44 | bl[i].SetColor(BLACK) 45 | } 46 | } 47 | 48 | func (c Color) String() string { 49 | strings := []string{"WHITE", "BLACK", "BLUE", "RED", "YELLOW"} 50 | return strings[c] 51 | } 52 | 53 | func main() { 54 | boxes := BoxList{ 55 | Box{4, 4, 4, RED}, 56 | Box{10, 10, 1, YELLOW}, 57 | Box{1, 1, 20, BLACK}, 58 | Box{10, 10, 1, BLUE}, 59 | Box{10, 30, 1, WHITE}, 60 | Box{20, 20, 20, YELLOW}, 61 | } 62 | 63 | fmt.Printf("We have %d boxes in our set\n", len(boxes)) 64 | fmt.Println("The volume of the first one is", boxes[0].Volume(), "cm³") 65 | fmt.Println("The color of the last one is", boxes[len(boxes)-1].color.String()) 66 | fmt.Println("The biggest one is", boxes.BiggestsColor().String()) 67 | 68 | fmt.Println("Let's paint them all black") 69 | boxes.PaintItBlack() 70 | fmt.Println("The color of the second one is", boxes[1].color.String()) 71 | 72 | fmt.Println("Obviously, now, the biggest one is", boxes.BiggestsColor().String()) 73 | } 74 | -------------------------------------------------------------------------------- /eBook/14.0.md: -------------------------------------------------------------------------------- 1 | # 14 Desarrollar framework web 2 | 3 | Capítulo XIII describe cómo desarrollar un marco Web, mediante la introducción de la MVC, enrutamiento, procesamiento de registros, el proceso de configuración se completa un marco básico para el sistema, pero un buen marco requiere de algunas herramientas auxiliares para facilitar el rápido desarrollo de la Web, entonces este capítulo proporcionará alguna rápida cómo desarrollar se introducen las herramientas basadas en la web, la primera sección se explica qué hacer con los archivos estáticos, como usar Twitter existente de código abierto de arranque para el desarrollo rápido de sitios hermosos, la segunda sección se describe cómo utilizar la anteriormente describe la sesión de registro de usuario en el proceso, y la tercera sección se describe cómo las formas de salida conveniente que la forma en la validación de datos, con qué rapidez los datos del modelo para las operaciones CRUD de unión, la cuarta sección se describe cómo realizar algunas de autenticación de usuario, incluida la certificación básica http, http la autenticación implícita, la quinta sección se describe cómo utilizar el soporte de i18n desarrollo de aplicaciones multi-lenguaje descrito anteriormente. 4 | 5 | En esta expansión capítulo, beego marco tendrá un rápido desarrollo de las propiedades de la Web, y, finalmente, vamos a explicar cómo utilizar las características de estos sistemas de blog de desarrollo de extensión extensiones desarrollado en el Capítulo XIII, a través del desarrollo de un sistema de blog completo, hermosa permite que los lectores entender beego desarrollo trae rápido. 6 | ## Links 7 | 8 | - [Directory](preface.md) 9 | - Previous chapter: [Chapter 13 summary](13.6.md) 10 | - Next section: [Static files](14.1.md) 11 | -------------------------------------------------------------------------------- /code/src/apps/ch.4.5/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 4.5 2 | // Purpose is to create a server to handle uploading files. 3 | package main 4 | 5 | import ( 6 | "apps/ch.4.4/nonce" 7 | "apps/ch.4.4/validator" 8 | "fmt" 9 | "html/template" 10 | "io" 11 | "mime/multipart" 12 | "net/http" 13 | "os" 14 | ) 15 | 16 | const MiB_UNIT = 1 << 20 17 | 18 | var t *template.Template 19 | var submissions nonce.Nonces = nonce.New() 20 | 21 | func checkError(err error) { 22 | if err != nil { 23 | panic(err) 24 | } 25 | } 26 | func indexHandler(w http.ResponseWriter, r *http.Request) { 27 | err := t.ExecuteTemplate(w, "index", submissions.NewToken()) 28 | checkError(err) 29 | } 30 | func uploadHandler(w http.ResponseWriter, r *http.Request) { 31 | var errs validator.Errors 32 | r.ParseMultipartForm(32 * MiB_UNIT) 33 | token := r.Form.Get("token") 34 | if err := submissions.CheckThenMarkToken(token); err != nil { 35 | errs = validator.Errors{[]error{err}} 36 | } else { 37 | file, handler, err := r.FormFile("uploadfile") 38 | checkError(err) 39 | saveUpload(file, handler) 40 | } 41 | err := t.ExecuteTemplate(w, "upload", errs) 42 | checkError(err) 43 | } 44 | func saveUpload(file multipart.File, handler *multipart.FileHeader) { 45 | defer file.Close() 46 | fmt.Printf("Uploaded file info: %#v", handler.Header) 47 | localFilename := fmt.Sprintf("./uploads/%v.%v", handler.Filename, submissions.NewToken()) 48 | f, err := os.OpenFile(localFilename, os.O_WRONLY|os.O_CREATE, 0666) 49 | checkError(err) 50 | defer f.Close() 51 | _, err = io.Copy(f, file) 52 | checkError(err) 53 | } 54 | func init() { 55 | var err error 56 | t, err = template.ParseFiles("index.gtpl", "upload.gtpl") 57 | checkError(err) 58 | } 59 | func main() { 60 | http.HandleFunc("/", indexHandler) 61 | http.HandleFunc("/upload", uploadHandler) 62 | err := http.ListenAndServe(":9090", nil) 63 | checkError(err) 64 | } 65 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.6/interface/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | import "fmt" 3 | 4 | type Human struct { 5 | name string 6 | age int 7 | phone string 8 | } 9 | 10 | type Student struct { 11 | Human 12 | school string 13 | loan float32 14 | } 15 | 16 | type Employee struct { 17 | Human 18 | company string 19 | money float32 20 | } 21 | 22 | func (h Human) SayHi() { 23 | fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone) 24 | } 25 | 26 | func (h Human) Sing(lyrics string) { 27 | fmt.Println("La la la la...", lyrics) 28 | } 29 | 30 | func (e Employee) SayHi() { 31 | fmt.Printf("Hi, I am %s, I work at %s. Call me on %s\n", e.name, 32 | e.company, e.phone) //Yes you can split into 2 lines here. 33 | } 34 | 35 | // Interface Men implemented by Human, Student and Employee 36 | type Men interface { 37 | SayHi() 38 | Sing(lyrics string) 39 | } 40 | 41 | func main() { 42 | mike := Student{Human{"Mike", 25, "222-222-XXX"}, "MIT", 0.00} 43 | paul := Student{Human{"Paul", 26, "111-222-XXX"}, "Harvard", 100} 44 | sam := Employee{Human{"Sam", 36, "444-222-XXX"}, "Golang Inc.", 1000} 45 | Tom := Employee{Human{"Sam", 36, "444-222-XXX"}, "Things Ltd.", 5000} 46 | 47 | // define interface i 48 | var i Men 49 | 50 | //i can store Student 51 | i = mike 52 | fmt.Println("This is Mike, a Student:") 53 | i.SayHi() 54 | i.Sing("November rain") 55 | 56 | //i can store Employee 57 | i = Tom 58 | fmt.Println("This is Tom, an Employee:") 59 | i.SayHi() 60 | i.Sing("Born to be wild") 61 | 62 | // slice of Men 63 | fmt.Println("Let's use a slice of Men and see what happens") 64 | x := make([]Men, 3) 65 | // these three elements are different types but they all implemented interface Men 66 | x[0], x[1], x[2] = paul, sam, mike 67 | 68 | for _, value := range x{ 69 | value.SayHi() 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /code/src/apps/ch.4.2/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 4.2 from "Build Web Application with Golang" 2 | // Purpose: Shows how to perform server-side validation of user input from a form. 3 | // Also shows to use multiple template files with predefined template names. 4 | // Run `go run main.go` and then access http://localhost:9090 5 | package main 6 | 7 | import ( 8 | "apps/ch.4.2/validator" 9 | "html/template" 10 | "log" 11 | "net/http" 12 | ) 13 | 14 | const ( 15 | PORT = "9090" 16 | HOST_URL = "http://localhost:" + PORT 17 | ) 18 | 19 | var t *template.Template 20 | 21 | type Links struct { 22 | BadLinks [][2]string 23 | } 24 | 25 | // invalid links to display for testing. 26 | var links Links 27 | 28 | func index(w http.ResponseWriter, r *http.Request) { 29 | http.Redirect(w, r, HOST_URL+"/profile", http.StatusTemporaryRedirect) 30 | } 31 | func profileHandler(w http.ResponseWriter, r *http.Request) { 32 | t.ExecuteTemplate(w, "profile", links) 33 | } 34 | func checkProfile(w http.ResponseWriter, r *http.Request) { 35 | r.ParseForm() 36 | p := validator.ProfilePage{&r.Form} 37 | t.ExecuteTemplate(w, "submission", p.GetErrors()) 38 | } 39 | 40 | // This function is called before main() 41 | func init() { 42 | // Note: we can reference the loaded templates by their defined name inside the template files. 43 | t = template.Must(template.ParseFiles("profile.gtpl", "submission.gtpl")) 44 | 45 | list := make([][2]string, 2) 46 | list[0] = [2]string{HOST_URL + "/checkprofile", "No data"} 47 | list[1] = [2]string{HOST_URL + "/checkprofile?age=1&gender=guy&shirtsize=big", "Invalid options"} 48 | links = Links{list} 49 | } 50 | func main() { 51 | http.HandleFunc("/", index) 52 | http.HandleFunc("/profile", profileHandler) 53 | http.HandleFunc("/checkprofile", checkProfile) 54 | 55 | err := http.ListenAndServe(":"+PORT, nil) // setting listening port 56 | if err != nil { 57 | log.Fatal("ListenAndServe: ", err) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /code/src/apps/ch.5.3/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 5.3 from "Build Web Application with Golang" 2 | // Purpose: Shows how to run simple CRUD operations using a sqlite driver 3 | package main 4 | 5 | import ( 6 | "database/sql" 7 | "fmt" 8 | _ "github.com/mattn/go-sqlite3" 9 | "time" 10 | ) 11 | 12 | const DB_PATH = "./foo.db" 13 | 14 | func main() { 15 | db, err := sql.Open("sqlite3", DB_PATH) 16 | checkErr(err) 17 | defer db.Close() 18 | 19 | fmt.Println("Inserting") 20 | stmt, err := db.Prepare("INSERT INTO userinfo(username, department, created) values(?,?,?)") 21 | checkErr(err) 22 | 23 | res, err := stmt.Exec("astaxie", "software developement", time.Now().Format("2006-01-02")) 24 | checkErr(err) 25 | 26 | id, err := res.LastInsertId() 27 | checkErr(err) 28 | 29 | fmt.Println("id of last inserted row =", id) 30 | fmt.Println("Updating") 31 | stmt, err = db.Prepare("update userinfo set username=? where uid=?") 32 | checkErr(err) 33 | 34 | res, err = stmt.Exec("astaxieupdate", id) 35 | checkErr(err) 36 | 37 | affect, err := res.RowsAffected() 38 | checkErr(err) 39 | 40 | fmt.Println(affect, "row(s) changed") 41 | 42 | fmt.Println("Querying") 43 | rows, err := db.Query("SELECT * FROM userinfo") 44 | checkErr(err) 45 | 46 | for rows.Next() { 47 | var uid int 48 | var username, department, created string 49 | err = rows.Scan(&uid, &username, &department, &created) 50 | checkErr(err) 51 | fmt.Println("uid | username | department | created") 52 | fmt.Printf("%3v | %6v | %8v | %6v\n", uid, username, department, created) 53 | } 54 | 55 | fmt.Println("Deleting") 56 | stmt, err = db.Prepare("delete from userinfo where uid=?") 57 | checkErr(err) 58 | 59 | res, err = stmt.Exec(id) 60 | checkErr(err) 61 | 62 | affect, err = res.RowsAffected() 63 | checkErr(err) 64 | 65 | fmt.Println(affect, "row(s) changed") 66 | } 67 | 68 | func checkErr(err error) { 69 | if err != nil { 70 | panic(err) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /eBook/13.0.md: -------------------------------------------------------------------------------- 1 | # 13 Construir un framework web 2 | 3 | Precediendo doce capítulos que describen cómo desarrollar aplicaciones Web a través de Go, se introdujo una gran cantidad de conocimientos, herramientas y técnicas básicas de desarrollo, entonces se pasa este conocimiento en este capítulo para implementar un marco Web simple en Go para lograr a través de un diseño de marco completo, el contenido principal de este marco, la primera sección se describe la estructura de un marco de planificación Web, como el uso del patrón MVC para desarrollar, diseñar proceso de ejecución del programa, etc; segunda sección describe el marco de la primera característica: Routing, cómo acceder a la URL asignada a la lógica de procesamiento correspondiente; tercera sección describe la lógica de procesamiento, cómo diseñar un controlador común, objeto de herencia después del manejador cómo manejar la respuesta y la petición; cuarta sección describe la forma de marco algunas funciones auxiliares, tales como el procesamiento de registros, información de configuración, etc; quinta sección se describe cómo implementar un marco basado en la Web blog, incluyendo Bowen publicó, modificar, eliminar, mostrar una lista de otras operaciones. 4 | 5 | A través de un ejemplo de proyecto tan completo, espero ser capaz de permitir a los lectores a entender cómo desarrollar aplicaciones Web, cómo construir su propia estructura de directorios, cómo lograr el enrutamiento, cómo lograr el patrón MVC y otros aspectos del desarrollo de contenidos. En el marco común hoy en día, MVC ya no es un mito. Muchos programadores a menudo escuchan discusiones que marco es bueno, lo que marco no es bueno, de hecho, el marco es sólo una herramienta, no hay nada bueno o malo, sólo apto o no apto, pero la suya es la mejor, así que escribir un propio marco , y luego diferentes segun las necesidades pueden utilizar sus propias ideas a hacerse realidad. 6 | 7 | ## Links 8 | 9 | - [Directory](preface.md) 10 | - Previous chapter: [Chapter 12 summary](12.5.md) 11 | - Next section: [Project program](13.1.md) 12 | -------------------------------------------------------------------------------- /code/src/apps/ch.5.2/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 5.2 from "Build Web Application with Golang" 2 | // Purpose: Use SQL driver to perform simple CRUD operations. 3 | package main 4 | 5 | import ( 6 | "database/sql" 7 | "fmt" 8 | _ "github.com/go-sql-driver/mysql" 9 | ) 10 | 11 | const ( 12 | DB_USER = "user" 13 | DB_PASSWORD = "" 14 | DB_NAME = "test" 15 | ) 16 | 17 | func main() { 18 | dbSouce := fmt.Sprintf("%v:%v@/%v?charset=utf8", DB_USER, DB_PASSWORD, DB_NAME) 19 | db, err := sql.Open("mysql", dbSouce) 20 | checkErr(err) 21 | defer db.Close() 22 | 23 | fmt.Println("Inserting") 24 | stmt, err := db.Prepare("INSERT userinfo SET username=?,departname=?,created=?") 25 | checkErr(err) 26 | 27 | res, err := stmt.Exec("astaxie", "software developement", "2012-12-09") 28 | checkErr(err) 29 | 30 | id, err := res.LastInsertId() 31 | checkErr(err) 32 | 33 | fmt.Println("id of last inserted row =", id) 34 | fmt.Println("Updating") 35 | stmt, err = db.Prepare("update userinfo set username=? where uid=?") 36 | checkErr(err) 37 | 38 | res, err = stmt.Exec("astaxieupdate", id) 39 | checkErr(err) 40 | 41 | affect, err := res.RowsAffected() 42 | checkErr(err) 43 | 44 | fmt.Println(affect, "row(s) changed") 45 | 46 | fmt.Println("Querying") 47 | rows, err := db.Query("SELECT * FROM userinfo") 48 | checkErr(err) 49 | 50 | for rows.Next() { 51 | var uid int 52 | var username, department, created string 53 | err = rows.Scan(&uid, &username, &department, &created) 54 | checkErr(err) 55 | fmt.Println("uid | username | department | created") 56 | fmt.Printf("%3v | %6v | %6v | %6v\n", uid, username, department, created) 57 | } 58 | 59 | fmt.Println("Deleting") 60 | stmt, err = db.Prepare("delete from userinfo where uid=?") 61 | checkErr(err) 62 | 63 | res, err = stmt.Exec(id) 64 | checkErr(err) 65 | 66 | affect, err = res.RowsAffected() 67 | checkErr(err) 68 | 69 | fmt.Println(affect, "row(s) changed") 70 | } 71 | 72 | func checkErr(err error) { 73 | if err != nil { 74 | panic(err) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /eBook/14.7.md: -------------------------------------------------------------------------------- 1 | # 14.7 Resumen 2 | 3 | En este capítulo se explica la forma de extender el marco basado en beego, que incluye soporte para los archivos estáticos, los archivos estáticos, principalmente acerca de cómo utilizar beego para el desarrollo web rápido utilizando bootstrap para construir un sitio precioso; segundo resumen explicando cómo beego en SessionManager integrada y fácil de usar en uso beego rápidamente cuando se utiliza período de sesiones; Tercero Resumen describe las formas y validación, basadas en el lenguaje Go nos permite definir una estructura en el proceso de desarrollo de la Web del trabajo repetitivo de la liberación, y se unió a la previa comprobación de la seguridad de datos puede ser en la medida de lo posible, el cuarto resumen describe la autenticación de usuarios, la autenticación de usuarios, hay tres requisitos principales, http básica y http digerir la certificación, la certificación de tercera parte, la certificación de encargo a través de código se muestra cómo utilizar el paquete tripartita sección existente integrado en aplicaciones beego para lograr estas certificaciones; quinta sección describe el soporte multi-idioma, beego go-i18n integrado esta multi-idioma paquete, los usuarios pueden utilizar fácilmente la biblioteca de desarrollo de aplicaciones web en varios idiomas; la sección sexta subsecciones describen cómo integrar paquetes pprof de Go, pprof paquete se utiliza para las herramientas de depuración de rendimiento, después de la transformación por beego paquete pprof integrado, lo que permite a los usuarios tomar ventaja de las aplicaciones basadas pprof beego prueba desarrollados por estos seis subsecciones nos introduce completo para abrir un relativamente sólido marco beego que es suficiente para satisfacer la mayoría de las aplicaciones web actuales, los usuarios pueden seguir desempeñando su imaginación para ampliar, estoy aquí sólo una breve introducción que se me ocurre para comparar varias extensiones importantes. 4 | 5 | ## Links 6 | 7 | - [Directory](preface.md) 8 | - Previous section: [pprof](14.6.md) 9 | - Next chapter: [Appendix A References](ref.md) 10 | 11 | -------------------------------------------------------------------------------- /eBook/04.0.md: -------------------------------------------------------------------------------- 1 | # 4 Formulario de entrada de los usuario 2 | 3 | Formulario de usuario es la herramienta que se utiliza comúnmente cuando desarrollamos aplicaciones web, proporciona capacidad de comunicación entre clientes y servidores. Usted debe conocer sobre form mucho si es de los desarrolladores web; si usted es + / programadores de C de C +, es posible que desee preguntar: ¿cuál es el formulario de usuario? 4 | 5 | El Formulario es el área que contiene los elementos del formulario. Los usuarios pueden introducir información en estos elementos, como el cuadro de texto, en la lista desplegable, botones de opción, casilla de verificación, etc. Utilizamos form tag
para definir el formulario. 6 | 7 | 8 | ... 9 | input elements 10 | ... 11 |
12 | 13 | Go tiene muchas funciones convenientes para hacer frente y dar forma a una aplicación, al igual que usted puede conseguir fácilmente los datos del formulario de peticiones HTTP,e integrar de manera facilos a sus propias aplicaciones Web. En la sección 4.1, vamos a hablar acerca de cómo manejar los datos del formulario en Go, y porque no se debe de confiar en todos los datos de los clientes, usted tiene que verificar los datos antes de usarlos. Después de eso, vamos a mostrar algunos ejemplos acerca de la verificación de los datos del formulario en la sección 4.2. 14 | 15 | Decimos que HTTP no tiene estado, ¿cómo podemos identificar que estos formularios son de un mismo usuario? Y la manera de asegurarse de que un formulario sólo puede presentarse una vez? Tenemos una explicación más detallada acerca del cookie (cookie es la información que se puede guardar en el lado del cliente, y poner en el encabezado de la solicitud que se envía con al servidor) en ambas secciones 4.3 y 4.4. 16 | 17 | Otra gran característica de form es subir los archivos. En la sección 4.5, usted aprenderá cómo usar esta característica y controlar el tamaño del archivo antes de que comience la carga en Go. 18 | 19 | ## Enlaces 20 | 21 | - [Indice](preface.md) 22 | - Sección anterior: [Resumen](03.5.md) 23 | - Siguiente sección: [Procesando la entrada de los formularios](04.1.md) 24 | -------------------------------------------------------------------------------- /code/src/apps/ch.5.4/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 5.4 from "Build Web Application with Golang" 2 | // Purpose: Show how to perform CRUD operations using a postgres driver 3 | package main 4 | 5 | import ( 6 | "database/sql" 7 | "fmt" 8 | _ "github.com/bmizerany/pq" 9 | "time" 10 | ) 11 | 12 | const ( 13 | DB_USER = "user" 14 | DB_PASSWORD = "" 15 | DB_NAME = "test" 16 | ) 17 | 18 | func main() { 19 | dbinfo := fmt.Sprintf("user=%s password=%s dbname=%s sslmode=disable", 20 | DB_USER, DB_PASSWORD, DB_NAME) 21 | db, err := sql.Open("postgres", dbinfo) 22 | checkErr(err) 23 | defer db.Close() 24 | 25 | fmt.Println("# Inserting values") 26 | 27 | var lastInsertId int 28 | err = db.QueryRow("INSERT INTO userinfo(username,departname,created) VALUES($1,$2,$3) returning uid;", 29 | "astaxie", "software developement", "2012-12-09").Scan(&lastInsertId) 30 | checkErr(err) 31 | fmt.Println("id of last inserted row =", lastInsertId) 32 | 33 | fmt.Println("# Updating") 34 | stmt, err := db.Prepare("update userinfo set username=$1 where uid=$2") 35 | checkErr(err) 36 | 37 | res, err := stmt.Exec("astaxieupdate", lastInsertId) 38 | checkErr(err) 39 | 40 | affect, err := res.RowsAffected() 41 | checkErr(err) 42 | 43 | fmt.Println(affect, "row(s) changed") 44 | 45 | fmt.Println("# Querying") 46 | rows, err := db.Query("SELECT * FROM userinfo") 47 | checkErr(err) 48 | 49 | for rows.Next() { 50 | var uid int 51 | var username string 52 | var department string 53 | var created time.Time 54 | err = rows.Scan(&uid, &username, &department, &created) 55 | checkErr(err) 56 | fmt.Println("uid | username | department | created ") 57 | fmt.Printf("%3v | %8v | %6v | %6v\n", uid, username, department, created) 58 | } 59 | 60 | fmt.Println("# Deleting") 61 | stmt, err = db.Prepare("delete from userinfo where uid=$1") 62 | checkErr(err) 63 | 64 | res, err = stmt.Exec(lastInsertId) 65 | checkErr(err) 66 | 67 | affect, err = res.RowsAffected() 68 | checkErr(err) 69 | 70 | fmt.Println(affect, "row(s) changed") 71 | } 72 | 73 | func checkErr(err error) { 74 | if err != nil { 75 | panic(err) 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /eBook/09.0.md: -------------------------------------------------------------------------------- 1 | # 9 Seguridad y encriptacion 2 | 3 | La seguridad es importante con la aplicación Web. Este tema estado recibiendo cada vez más atención últimamente, especialmente en los últimos CSDN, Linkedin y Yahoo filtraciones de contraseñas. Como desarrolladores Go, debemos ser conscientes de las vulnerabilidades de nuestra aplicación y tomar las precauciones necesarias para evitar que los atacantes se apoderen de nuestro sistema. 4 | 5 | Muchos de los problemas de seguridad de aplicaciones Web se deben a los datos proporcionados por un tercero. Por ejemplo, la entrada del usuario debe ser validado y desinfectarse antes de ser almacenados como datos seguros. Si esto no se hace a continuación, cuando los datos se da salida al cliente, puede causar un ataque de cross-site scripting (XSS). Si los datos no seguro se utiliza consultas de base de datos, entonces puede causar una inyección SQL. En las secciones 9.3, 9.4 veremos cómo evitar estos problemas. 6 | 7 | Al utilizar datos de terceros, incluidos los datos suministrados por el usuario, primero verificar la integridad de los datos mediante el filtrado de la entrada. Sección 9.2 describe cómo filtrar entrada. 8 | 9 | Por desgracia, el filtrado de entrada y salida de escape no resuelve todos los problemas de seguridad. Vamos a explicar en la sección 9.1 de cross-site request forgery (CSRF). Se trata de una explotación maliciosa de un sitio web mediante el cual se transmiten comandos no autorizados de un usuario que confía el sitio web. 10 | 11 | Adición de encriptación también puede incluir la seguridad de nuestra aplicación web. En la sección 9.5 describimos cómo almacenar contraseñas de forma segura. 12 | 13 | Una buena función hash hace que sea difícil encontrar dos cadenas que producirían el mismo valor hash, que describe una forma de cifrado. Existe también el cifrado de dos vías, que es donde se utiliza una clave para descifrar los datos cifrados. En la sección 9.6 describimos cómo realizar una sola vía y el cifrado de dos vías. 14 | 15 | Enlaces. 16 | 17 | 18 | ## Links 19 | - [Directory](preface.md) 20 | - Previous Chapter: [Chapter 8 Summary](08.5.md) 21 | - Next section: [CSRF attacks](09.1.md) 22 | -------------------------------------------------------------------------------- /eBook/08.0.md: -------------------------------------------------------------------------------- 1 | # 8 Servicios Web 2 | 3 | Los servicios Web le permite utilizar formatos como XML o JSON para intercambiar información a través de HTTP. Por ejemplo, usted quiere saber el tiempo de Shanghai mañana, precio de las acciones de Apple, o información de producto en Amazon, usted puede escribir un pedazo de código para obtener información de las plataformas abiertas, como se llama a una función local y obtener su valor de retorno. 4 | 5 | El punto clave es que los servicios Web son la independencia de plataforma, que le permite desplegar sus aplicaciones en Linux y interactiva con las aplicaciones ASP.NET de Windows; lo mismo, no hay ningún problema de interactuar con JSP en FreeBSD también. 6 | 7 | REST y SOAP son los servicios web más populares en estos días: 8 | 9 | - Las solicitudes de REST es bastante sencillo, ya que está basado en HTTP. Cada solicitud de REST es en realidad una petición HTTP, y el mango servidor de peticiones por diferentes métodos lógicos. Debido a que muchos desarrolladores saben HTTP mucho ya, REST es como en sus bolsillos traseros. Vamos a decirles cómo implementar REST en Go en la sección 8.3. 10 | - SOAP un estándar de transmisión a través de la información de la red y las llamadas a funciones de ordenador a distancia, que se pusieron en marcha por el W3C. El problema de SOAP es que su especificación es muy largo y complicado, y todavía está haciendo más grande. Go cree que las cosas deben ser simples, por lo que no vamos a hablar de SOAP. Afortunadamente, Go ofrece RPC que tiene un buen rendimiento y fáciles de desarrollar, por lo que presentará cómo implementar RPC en Go en la sección 8.4. 11 | 12 | Go es el lenguaje C de siglo 21, aspiramos sencilla y el rendimiento, a continuación, vamos a presentar la programación de sockets en Go en la sección 8.1, ya que muchos servidores de juegos están utilizando Socket debido al bajo rendimiento de HTTP. Junto con el rápido desarrollo de HTML5, websockets son utilizados por muchas compañías de la página del juego, y vamos a hablar de esto más en la sección 8.2. 13 | 14 | ## Links 15 | 16 | - [Directory](preface.md) 17 | - Previous Chapter: [Chapter 7 Summary](07.7.md) 18 | - Next section: [Sockets](08.1.md) 19 | -------------------------------------------------------------------------------- /eBook/10.0.md: -------------------------------------------------------------------------------- 1 | # 10 Internacionalización y localización 2 | 3 | Con el fin de adaptarse a la globalización, como desarrollador, tenemos que desarrollar un multilingües aplicaciones web internacionales. Esto significa que la misma página en un entorno de idioma distinto necesita demostrar un efecto diferente. Por ejemplo, la aplicación en tiempo de ejecución de acuerdo con la solicitud de las diferencias geográficas y lingüísticas y mostrar una interfaz de usuario diferente. Así, cuando una aplicación necesita para añadir soporte para un nuevo idioma, la necesidad de modificar el código de la aplicación, sólo tiene que añadir paquetes de idiomas puede ser observada. 4 | 5 | Internacionalización y Localización (generalmente expresado como i18n y L10N), la internacionalización es un área diseñada para el programa de reconstrucción para que pueda utilizar en más zonas, la localización se refiere a una cara programas internacionales para aumentar el apoyo a la nueva región. 6 | 7 | Actualmente, Go paquete estándar del lenguaje no ofrece soporte i18n, pero hay algunas implementaciones relativamente simples de terceros de este capítulo vamos a lograr una biblioteca go-i18n para apoyar la i18n lenguaje Go. 8 | 9 | El llamado Internacional: se basa en una información de configuración regional específica, se extrajo con la cadena correspondiente o algunas otras cosas (tales como el tiempo y formato de moneda) y así sucesivamente. Esto implica tres cuestiones: 10 | 11 | 1. cómo determinar la configuración regional. 12 | 13 | 2. cómo guardar la cadena asociada a la configuración regional o de otra información. 14 | 15 | 3. cómo extraer de acuerdo a las cadenas de localización y otra información apropiada. 16 | 17 | En la primera sección, describiremos cómo establecer la configuración regional correcta con el fin de permitir el acceso a los usuarios del sitio para obtener su página correspondiente idioma. La segunda sección describe cómo manejar o almacenar cadenas, moneda, hora, fecha y otra información relacionada con la configuración regional, y la tercera sección se describe la forma de lograr un sitio, es decir, cómo devolver diferente según la zona de contenido apropiado. A través de estas tres secciones de estudio, vamos a conseguir un programa i18n completo. 18 | 19 | ## Links 20 | 21 | - [Directory](preface.md) 22 | - Previous Chapter: [Chapter 9 Summary](09.7.md) 23 | - Next section: [Time zone](10.1.md) 24 | -------------------------------------------------------------------------------- /eBook/11.0.md: -------------------------------------------------------------------------------- 1 | # 11 Manejo de errores, depurar y probar 2 | 3 | A menudo vemos la mayor parte del tiempo "programación" de un programador dedicado a la comprobación de errores y trabajando en correcciones de errores. Si usted está dispuesto a modificar el código o los sistemas de re-configurables, casi todo pasa mucho tiempo de resolución de problemas y pruebas, nos parece que el mundo exterior es un programador diseñador, capaz de poner un sistema nunca lo ha hecho, es una obra muy grande , pero el trabajo es muy interesante, pero en realidad todos los días nos están vagando en la solución de problemas, depuración, prueba el medio. Por supuesto, si usted tiene buenos hábitos y soluciones de tecnología para hacer frente a estas preguntas, entonces usted está probablemente para minimizar el tiempo de resolución de problemas, y tanto como sea posible para pasar el tiempo en las cosas más valiosas. 4 | 5 | Pero, por desgracia muchos programadores capacidades de manejo de errores, depuración y pruebas que no quieren trabajar, que conduce a la parte de atrás en la línea después de la aplicación de los errores, el posicionamiento pasa más tiempo. Así que hacemos un buen trabajo en el diseño de la aplicación antes de que el plan de control de errores, casos de prueba, etc, entonces el futuro para modificar el código, actualice el sistema a ser más simple. 6 | 7 | Proceso de desarrollo de aplicaciones Web, los errores son inevitables, por lo que la mejor manera de encontrar la causa del error, solucionar el problema? Sección 11.1 describe cómo controlar los errores Ir lenguaje, la forma de diseñar su propio paquete, la función de control de errores, 11,2 sección describe cómo usar GDB para depurar nuestro programa, el funcionamiento dinámico de la diversa información variable de seguimiento del tránsito y la depuración. 8 | 9 | Sección 11.3 del lenguaje Go explorará en profundidad las pruebas unitarias y ejemplos de cómo escribir pruebas unitarias, vaya especificación prueba unitaria cómo definir reglas para garantizar que las futuras actualizaciones de modificar ejecutar el código de prueba adecuado puede minimizar prueba. 10 | 11 | Durante mucho tiempo, desarrollar una buena depuración, las pruebas han sido un montón de programadores acostumbrados a evadir la cosa, por lo que ahora no escapar, de su desarrollo actual del proyecto, desde el principio de aprender Go a los desarrolladores web para desarrollar buenos hábitos. 12 | 13 | ## Links 14 | 15 | - [Directory](preface.md) 16 | - Previous chapter: [Chapter 10 summary](10.4.md) 17 | - Next section: [Error handling](11.1.md) 18 | -------------------------------------------------------------------------------- /eBook/03.2.md: -------------------------------------------------------------------------------- 1 | # 3.2 Armando un servidor web sencillo 2 | 3 | Hablamos de que las aplicaciones web se basan en el protocolo HTTP, y Go permite la plena capacidad para HTTP en el paquete `net/http`, es muy fácil instalar un servidor web mediante el uso de este paquete . 4 | 5 | ## Uso del paquete http para configurar un servidor web 6 | 7 | package main 8 | 9 | import ( 10 | "fmt" 11 | "net/http" 12 | "strings" 13 | "log" 14 | ) 15 | 16 | func sayhelloName(w http.ResponseWriter, r *http.Request) { 17 | r.ParseForm() //analizar argumentos , tiene que llamar a esto por su cuenta 18 | fmt.Println(r.Form) //imprime información en el form en el lado del servidor 19 | fmt.Println("path", r.URL.Path) 20 | fmt.Println("scheme", r.URL.Scheme) 21 | fmt.Println(r.Form["url_long"]) 22 | for k, v := range r.Form { 23 | fmt.Println("key:", k) 24 | fmt.Println("val:", strings.Join(v, "")) 25 | } 26 | fmt.Fprintf(w, "Hello astaxie!") // enviar datos al lado del cliente 27 | } 28 | 29 | func main() { 30 | http.HandleFunc("/", sayhelloName) // define la ruta 31 | err := http.ListenAndServe(":9090", nil) // establece el puerto de escucha 32 | if err != nil { 33 | log.Fatal("ListenAndServe: ", err) 34 | } 35 | } 36 | 37 | Después de ejecutar el código anterior, el host Local empieza a escuchar en el puerto 9090. 38 | 39 | Abra su navegador y visite `http://localhost:9090`, se puede ver que `Hello astaxie` está en su pantalla . 40 | 41 | Vamos a intentar otra dirección con argumentos : `http://localhost:9090/?url_long=111&url_long=222` 42 | 43 | Ahora veamos lo que sucedió en los dos lados de cliente y servidor . 44 | 45 | Usted debe ver la siguiente información en su lado del servidor : 46 | 47 | ![](images/3.2.goweb.png?raw=true) 48 | 49 | Figura 3.8 Información del servidor por pantalla 50 | 51 | Como se puede ver, sólo tenemos que llamar a dos funciones para crear un servidor web simple . 52 | 53 | Si está trabajando con PHP, es probable que desee preguntar qué necesitamos algo como Nginx o Apache , la respuesta es que no necesitamos porque GO escucha el puerto TCP por sí mismo, y la `sayhelloName` función es la función lógica como controlador en PHP . 54 | 55 | Si está trabajando con Python , usted debe saber tornado , y el ejemplo anterior es muy similar a eso. 56 | 57 | Si está trabajando con Ruby, usted puede notar que es como script/server en ROR . 58 | 59 | Utilizamos dos funciones simples para configurar un servidor web simple en esta sección, y este servidor sencillo ya ha tenido capacidad para alta concurrencia. Vamos a hablar acerca de cómo usar esta característica en dos secciones siguientes . 60 | 61 | 62 | ## Enlaces 63 | 64 | - [Indice](preface.md) 65 | - Sección anterior: [Principios para el trabajo en la Web](03.1.md) 66 | - Siguiente sección: [Como trabaja Go con la web](03.3.md) 67 | -------------------------------------------------------------------------------- /code/src/apps/ch.4.4/profile.gtpl: -------------------------------------------------------------------------------- 1 | {{define "profile"}} 2 | 3 | 14 | 15 |

Profile Setup:

16 |
17 |
18 |
*User Name:
19 |
20 |
21 |
22 |
*Age:
23 |
24 |
25 |
26 |
*Email:
27 |
28 |
29 |
30 |
*Birth day:
31 |
32 | 33 |
34 |
35 |
36 |
Gender:
37 |
38 | 41 | 44 | 47 |
48 |
49 |
50 |
Siblings:
51 |
52 | 55 | 58 |
59 |
60 |
61 |
Shirt Size:
62 |
63 | 71 |
72 |
73 |
74 |
Chinese Name:
75 |
76 |
77 |
78 | *Required 79 |
80 | 81 | 82 |
83 | 84 | 85 | {{end}} 86 | -------------------------------------------------------------------------------- /code/src/apps/ch.4.2/profile.gtpl: -------------------------------------------------------------------------------- 1 | {{define "profile"}} 2 | 3 | 14 | 15 |

Profile Setup:

16 |
17 |
18 |
*User Name:
19 |
20 |
21 |
22 |
*Age:
23 |
24 |
25 |
26 |
*Email:
27 |
28 |
29 |
30 |
*Birth day:
31 |
32 | 33 |
34 |
35 |
36 |
Gender:
37 |
38 | 41 | 44 | 47 |
48 |
49 |
50 |
Siblings:
51 |
52 | 55 | 58 |
59 |
60 |
61 |
Shirt Size:
62 |
63 | 71 |
72 |
73 |
74 |
Chinese Name:
75 |
76 |
77 |
78 | *Required 79 |
80 | 81 |
82 |

Invalid submissions

83 |
    {{range .BadLinks}} 84 |
  1. {{index . 1}}
  2. 85 | {{end}} 86 |
87 | 88 | 89 | {{end}} -------------------------------------------------------------------------------- /eBook/04.4.md: -------------------------------------------------------------------------------- 1 | # 4.4 Envíos duplicados 2 | 3 | No sé si alguna vez has visto algunos blogs o BBS tienen más de un mensaje exactamente iguales, pero te puedo decir que es porque los usuarios hicieron presentaciones duplicadas de forma posterior a esa fecha. Hay lotes de razones puede causar envíos duplicados, a veces los usuarios sólo hacer doble clic en el botón de enviar, o que desee modificar algunos contenidos después del post y pulse el botón de nuevo, o es por el propósito de que usuarios malintencionados en algunos sitios web voto. Es fácil ver cómo los envíos duplicados llevan a muchos problemas, así que tenemos que utilizar medios eficaces para prevenirlo. 4 | 5 | La solución es que añadir un campo oculto con el token único a su forma, y ​​comprobar esta muestra cada vez antes de procesar los datos. Además, si usted está usando Ajax para enviar el formulario, utilice JavaScript para deshabilitar el botón una vez presentada presente. 6 | 7 | Mejoremos ejemplo en la sección 4.2: 8 | 9 | Football 10 | Basketball 11 | Tennis 12 | Username: 13 | Password: 14 | 15 | 16 | 17 | Se utilizó MD5 (sello de tiempo) para generar modo, y se añade a campo y la sesión oculto en el lado del servidor (capítulo 6), entonces podemos utilizar este token para comprobar si se ha presentado este formulario. 18 | 19 | func login(w http.ResponseWriter, r *http.Request) { 20 | fmt.Println("method:", r.Method) // get request method 21 | if r.Method == "GET" { 22 | crutime := time.Now().Unix() 23 | h := md5.New() 24 | io.WriteString(h, strconv.FormatInt(crutime, 10)) 25 | token := fmt.Sprintf("%x", h.Sum(nil)) 26 | 27 | t, _ := template.ParseFiles("login.gtpl") 28 | t.Execute(w, token) 29 | } else { 30 | // log in request 31 | r.ParseForm() 32 | token := r.Form.Get("token") 33 | if token != "" { 34 | // check token validity 35 | } else { 36 | // give error if no token 37 | } 38 | fmt.Println("username length:", len(r.Form["username"][0])) 39 | fmt.Println("username:", template.HTMLEscapeString(r.Form.Get("username"))) // print in server side 40 | fmt.Println("password:", template.HTMLEscapeString(r.Form.Get("password"))) 41 | template.HTMLEscape(w, []byte(r.Form.Get("username"))) // respond to client 42 | } 43 | } 44 | 45 | ![](images/4.4.token.png?raw=true) 46 | 47 | Figura 4.4 El contenido en el navegador después de añadido simbólico 48 | 49 | Usted puede volver a cargar esta página y verá diferente símbolo cada vez, por lo que este mantiene toda forma es única. 50 | 51 | Por ahora se puede prevenir muchos de los ataques de envíos duplicados mediante la adición de contadores a su forma, pero no puede prevenir todos los ataques engañosos, hay mucho más trabajo que debe hacerse. 52 | 53 | ## Enlaces 54 | 55 | - [Indice](preface.md) 56 | - Sección anterior: [Cross site scripting](04.3.md) 57 | - Siguiente sección: [Subida de archivos](04.5.md) 58 | -------------------------------------------------------------------------------- /code/src/apps/ch.2.3/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 2.3 from "Build Web Application with Golang" 2 | // Purpose: Goes over if, else, switch conditions, loops and defer. 3 | package main 4 | 5 | import "fmt" 6 | 7 | func computedValue() int { 8 | return 1 9 | } 10 | func show_if() { 11 | fmt.Println("\n#show_if()") 12 | x := computedValue() 13 | integer := 23 14 | 15 | fmt.Println("x =", x) 16 | fmt.Println("integer =", integer) 17 | if x > 10 { 18 | fmt.Println("x is greater than 10") 19 | } else { 20 | fmt.Println("x is less than 10") 21 | } 22 | 23 | if integer == 3 { 24 | fmt.Println("The integer is equal to 3") 25 | } else if integer < 3 { 26 | fmt.Println("The integer is less than 3") 27 | } else { 28 | fmt.Println("The integer is greater than 3") 29 | } 30 | } 31 | func show_if_var() { 32 | fmt.Println("\n#show_if_var()") 33 | // initialize x, then check if x greater than 34 | if x := computedValue(); x > 10 { 35 | fmt.Println("x is greater than 10") 36 | } else { 37 | fmt.Println("x is less than 10") 38 | } 39 | 40 | // the following code will not compile, since `x` is only accessable with the if/else block 41 | // fmt.Println(x) 42 | } 43 | func show_goto() { 44 | fmt.Println("\n#show_goto()") 45 | // The call to the label switches the goroutine it seems. 46 | i := 0 47 | Here: // label ends with ":" 48 | fmt.Println(i) 49 | i++ 50 | if i < 10 { 51 | goto Here // jump to label "Here" 52 | } 53 | } 54 | func show_for_loop() { 55 | fmt.Println("\n#show_for_loop()") 56 | sum := 0 57 | for index := 0; index < 10; index++ { 58 | sum += index 59 | } 60 | fmt.Println("part 1, sum is equal to ", sum) 61 | 62 | sum = 1 63 | // The compiler will remove the `;` from the line below. 64 | // for ; sum < 1000 ; { 65 | for sum < 1000 { 66 | sum += sum 67 | } 68 | fmt.Println("part 2, sum is equal to ", sum) 69 | 70 | for index := 10; 0 < index; index-- { 71 | if index == 5 { 72 | break // or continue 73 | } 74 | fmt.Println(index) 75 | } 76 | 77 | } 78 | func show_loop_through_map() { 79 | fmt.Println("\n#show_loop_through_map()") 80 | m := map[string]int{ 81 | "one": 1, 82 | "two": 2, 83 | "three": 3, 84 | } 85 | fmt.Println("map value = ", m) 86 | for k, v := range m { 87 | fmt.Println("map's key: ", k) 88 | fmt.Println("map's value: ", v) 89 | } 90 | } 91 | func show_switch() { 92 | fmt.Println("\n#show_switch()") 93 | i := 10 94 | switch i { 95 | case 1: 96 | fmt.Println("i is equal to 1") 97 | case 2, 3, 4: 98 | fmt.Println("i is equal to 2, 3 or 4") 99 | case 10: 100 | fmt.Println("i is equal to 10") 101 | default: 102 | fmt.Println("All I know is that i is an integer") 103 | } 104 | 105 | integer := 6 106 | fmt.Println("integer =", integer) 107 | switch integer { 108 | case 4: 109 | fmt.Println("integer == 4") 110 | fallthrough 111 | case 5: 112 | fmt.Println("integer <= 5") 113 | fallthrough 114 | case 6: 115 | fmt.Println("integer <= 6") 116 | fallthrough 117 | case 7: 118 | fmt.Println("integer <= 7") 119 | fallthrough 120 | case 8: 121 | fmt.Println("integer <= 8") 122 | fallthrough 123 | default: 124 | fmt.Println("default case") 125 | } 126 | } 127 | func show_defer() { 128 | fmt.Println("\nshow_defer()") 129 | defer fmt.Println("(last defer)") 130 | for i := 0; i < 5; i++ { 131 | defer fmt.Printf("%d ", i) 132 | } 133 | } 134 | func main() { 135 | show_if() 136 | show_if_var() 137 | show_goto() 138 | show_for_loop() 139 | show_loop_through_map() 140 | show_switch() 141 | show_defer() 142 | } 143 | -------------------------------------------------------------------------------- /eBook/04.3.md: -------------------------------------------------------------------------------- 1 | # 4.3 Cross site scripting 2 | 3 | Los sitios web de hoy tienen mucho más contenido dinámico con el fin de mejorar la experiencia del usuario, lo que significa que podemos ofrecer información dinámica depende de la conducta de cada individuo. Sin embargo, hay una cosa que se llama "secuencias de comandos entre sitio" (conocido como "XSS") siempre atacando sitios web dinámicos, y los sitios web estáticos son completamente bien en este momento. 4 | 5 | Los atacantes suelen inyectar scripts maliciosos como JavaScript, VBScript, ActiveX o Flash en los sitios web que tienen lagunas. Una vez que tengan la inyección de éxito, su información de usuario será robada y su sitio web se llena de correo no deseado, también se puede cambiar la configuración del usuario para lo que quieran. 6 | 7 | Si desea evitar este tipo de ataque, es mejor combinar los dos enfoques siguientes: 8 | 9 | - Verificación de todos los datos de los usuarios, lo que hemos hablado acerca de la sección anterior. 10 | - Dar un tratamiento especial para los datos que se respondieron a los clientes, con el fin de prevenir cualquier script inyectado se ejecuta en los navegadores. 11 | 12 | Entonces, ¿cómo le vamos a hacer estos dos puestos de trabajo en Go? Afortunadamente, el paquete de `html/template` tiene algunas funciones útiles para escapar de los datos de la siguiente manera: 13 | 14 | - `func HTMLEscape(w io.Writer, b []byte)` escapes b to w. 15 | - `func HTMLEscapeString(s string) string` returns string after escaped from s. 16 | - `func HTMLEscaper(args ...interface{}) string` returns string after escaped from multiple arguments. 17 | 18 | Vamos a cambiar el ejemplo de la sección 4.1: 19 | 20 | fmt.Println("username:", template.HTMLEscapeString(r.Form.Get("username"))) // print at server side 21 | fmt.Println("password:", template.HTMLEscapeString(r.Form.Get("password"))) 22 | template.HTMLEscape(w, []byte(r.Form.Get("username"))) // responded to clients 23 | 24 | Si tratamos de nombre de usuario de entrada como `` , vamos a ver el siguiente contenido en el navegador: 25 | 26 | ![](images/4.3.escape.png?raw=true) 27 | 28 | Figure 4.3 JavaScript after escaped 29 | 30 | Funciones en el paquete `html/template` plantilla ayuda a escapar de todas las etiquetas HTML, ¿y si lo que desea es imprimir `` en los navegadores? Usted debe utilizar `text/template` en su lugar. 31 | 32 | import "text/template" 33 | ... 34 | t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`) 35 | err = t.ExecuteTemplate(out, "T", "") 36 | 37 | Output: 38 | 39 | Hello, ! 40 | 41 | O puede utilizar el tipo `template.HTML` : 42 | El contenido de la variable no será escapado si su tipo es `template.HTML` . 43 | 44 | import "html/template" 45 | ... 46 | t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`) 47 | err = t.ExecuteTemplate(out, "T", template.HTML("")) 48 | 49 | Salida: 50 | 51 | Hello, ! 52 | 53 | One more example of escape 54 | 55 | import "html/template" 56 | ... 57 | t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`) 58 | err = t.ExecuteTemplate(out, "T", "") 59 | 60 | salida: 61 | 62 | Hello, <script>alert('you have been pwned')</script>! 63 | 64 | ## Enlaces 65 | 66 | - [Indice](preface.md) 67 | - Sección anterior: [Verificando las entradas](04.2.md) 68 | - Siguiente sección: [Envíos duplicados](04.4.md) 69 | -------------------------------------------------------------------------------- /eBook/02.1.md: -------------------------------------------------------------------------------- 1 | # 2.1 Hello, Go 2 | 3 | Antes de empezar a escribir aplicaciones en Go, necesitamos aprender como escribir programas sencillos. Es por eso mismo que uno no puede construir un edificio sin antes saber construir sus cimientos. Por esto en esta sección, vamos a aprender la sintaxis básica para poder escribir y correr algunos programas sencillos. 4 | 5 | ## Programa 6 | 7 | De acuerdo a la práctica internacional, antes de aprender a programar en muchos lenguajes, usted puede estar buscando como escribir un programa que imprima la frase "Hello world". 8 | 9 | Estas listo? Comencemos! 10 | 11 | package main 12 | 13 | import "fmt" 14 | 15 | func main() { 16 | fmt.Printf("Hello, world or 你好,世界 or καλημ ́ρα κóσμ or こんにちは世界\n") 17 | } 18 | 19 | Esto va a imprimir lo siguiente. 20 | 21 | Hello, world or 你好,世界 or καλημ ́ρα κóσμ or こんにちは世界 22 | 23 | ## Explicación 24 | 25 | Una de las cosas que debe saber en primer lugar es que los programas escritos en Go, están compuestos por `paquetes` (`package`). 26 | 27 | `package` (En este caso es `package main`) esto nos dice que el archivo fuente pertenece al paquete `main`, y la palabra clave `main` nos dice que este paquete se compilara formando un programa en lugar de en archivos de paquetes los cuales tienen la extensión `.a`. 28 | 29 | Todo programa ejecutable tiene uno y solo un paquete `main`, y este necesita tener una función de arranque llamada `main` sin ningún argumento o valor de retorno en el mismo paquete `main`. 30 | 31 | Para poder imprimir `Hello, world…`, debemos llamar a la función llamada `Printf`. Esta función se encuentra en el paquete `fmt`, por eso necesitamos importar este paquete en la tercer línea del código fuente, que es `import "fmt"` 32 | 33 | La forma de pensar sobre los paquetes en Go es similar a Python, y tienen algunas ventajas: Modularidad (separar tus programas en varios módulos) y la reusabilidad (todo modulo se puede rehusar en cualquier programa). Acabamos de hablar del concepto de paquetes y mas tarde vamos a construir nuestros propios paquetes. 34 | 35 | En la quinta linea, utilizamos la palabra clave `func` para definir la función `main`. El cuerpo de la función se encuentra dentro de los `{}`, al igual que en C, C++ y Java. 36 | 37 | Como puede ver, no tiene argumentos. Mas adelante vamos a ver como podemos escribir funciones con argumentos en unos segundos, y también como tener funciones que tienen valores de retorno o no. 38 | 39 | En la sexta línea llamamos a la función `Printf` que es del paquete `fmt`. Esta llamada se realiza con la siguiente sintaxis `.`, que es muy similar al estilo de Python. 40 | 41 | Como mencionamos en el capítulo 1, el nombre del paquete y el nombre de la carpeta que contiene el paquete pueden ser diferentes. Acá el `` viene de el nombre en `package `, no del nombre de la carpeta. 42 | 43 | Como se puede ver en el ejemplo este contiene muchos caracteres en ejemplo que no son caracteres ASCII. Esto es apropósito y es para mostrarte que por defecto Go soporta UTF-8. Usted puede utilizar cualquier carácter UTF-8 en sus programas. 44 | 45 | ## Conclusión 46 | 47 | Go utiliza `package` (como módulos en Python) para organizar sus programas. La función `main.main()` (esta función debe estar en el paquete llamado `main`) es el punto de arranque de cualquier programa. Go soporta caracteres UTF-8 debido a que uno de los creadores de Go es el creador de UTF-8, por lo que Go soporta múltiples-lenguajes desde el momento de su nacimiento. 48 | 49 | ## Enlaces 50 | 51 | - [Indice](preface.md) 52 | - Sección anterior: [Conocimientos básicos sobre Go](02.0.md) 53 | - Siguiente sección: [Principios de Go](02.2.md) 54 | -------------------------------------------------------------------------------- /eBook/14.5.md: -------------------------------------------------------------------------------- 1 | # 14.5 El soporte multi-idioma 2 | 3 | Hemos introducido en el capítulo de internacionalización y localización, hemos desarrollado una biblioteca de go-i18n, la biblioteca esta sección vamos a integrar beego marco interior, por lo que nuestro marco es compatible con la internacionalización y localización. 4 | 5 | ## Integración I18n 6 | 7 | beego variable global se establece de la siguiente manera: 8 | 9 | Translation i18n.IL 10 | Lang string // set the language pack, zh, en 11 | LangPath string // set the language pack location 12 | 13 | Función multi-idioma para inicializar: 14 | 15 | func InitLang(){ 16 | beego.Translation:=i18n.NewLocale() 17 | beego.Translation.LoadPath(beego.LangPath) 18 | beego.Translation.SetLocale(beego.Lang) 19 | } 20 | 21 | Con el fin de facilitar la más llamada directa en el paquete de idioma de la plantilla, hemos diseñado tres funciones para manejar la respuesta de múltiples idiomas: 22 | 23 | beegoTplFuncMap["Trans"] = i18n.I18nT 24 | beegoTplFuncMap["TransDate"] = i18n.I18nTimeDate 25 | beegoTplFuncMap["TransMoney"] = i18n.I18nMoney 26 | 27 | func I18nT(args ...interface{}) string { 28 | ok := false 29 | var s string 30 | if len(args) == 1 { 31 | s, ok = args[0].(string) 32 | } 33 | if !ok { 34 | s = fmt.Sprint(args...) 35 | } 36 | return beego.Translation.Translate(s) 37 | } 38 | 39 | func I18nTimeDate(args ...interface{}) string { 40 | ok := false 41 | var s string 42 | if len(args) == 1 { 43 | s, ok = args[0].(string) 44 | } 45 | if !ok { 46 | s = fmt.Sprint(args...) 47 | } 48 | return beego.Translation.Time(s) 49 | } 50 | 51 | func I18nMoney(args ...interface{}) string { 52 | ok := false 53 | var s string 54 | if len(args) == 1 { 55 | s, ok = args[0].(string) 56 | } 57 | if !ok { 58 | s = fmt.Sprint(args...) 59 | } 60 | return beego.Translation.Money(s) 61 | } 62 | 63 | ## Utiliza el desarrollo de multi-idioma 64 | 65 | 1. Establecer la ubicación de idiomas y paquetes de idioma, entonces inicializar los objetos i18n: 66 | 67 | beego.Lang = "zh" 68 | beego.LangPath = "views/lang" 69 | beego.InitLang() 70 | 71 | 2. Paquete de Diseño Multi-language 72 | 73 | Lo anterior se habla de cómo inicializar paquete multi lenguaje, el paquete de idioma está ahora diseñando múltiples, el paquete multi-idioma es el archivo json, como se describe en el Capítulo X, tenemos que diseñar un documento sobre LangPath siguiente ejemplo zh.json o en.json 74 | 75 | # zh.json 76 | 77 | { 78 | "zh": { 79 | "submit": "提交", 80 | "create": "创建" 81 | } 82 | } 83 | 84 | #en.json 85 | 86 | { 87 | "en": { 88 | "submit": "Submit", 89 | "create": "Create" 90 | } 91 | } 92 | 93 | 3. Use el paquete de idioma 94 | 95 | Podemos llamar al controlador para obtener la respuesta de la traducción en idioma de traducción, de la siguiente manera: 96 | 97 | func (this *MainController) Get() { 98 | this.Data["create"] = beego.Translation.Translate("create") 99 | this.TplNames = "index.tpl" 100 | } 101 | 102 | También podemos llamar directamente a la respuesta en la función de traducción de plantilla: 103 | 104 | // Direct Text translation 105 | {{.create | Trans}} 106 | 107 | // Time to translate 108 | {{.time | TransDate}} 109 | 110 | // Currency translation 111 | {{.money | TransMoney}} 112 | 113 | ## Links 114 | 115 | - [Directory](preface.md) 116 | - Previous section: [User validation](14.4.md) 117 | - Next section: [pprof](14.6.md) 118 | 119 | -------------------------------------------------------------------------------- /eBook/preface.md: -------------------------------------------------------------------------------- 1 | - 1.[Configuración del entorno de desarrollo para Go](01.0.md) 2 | - 1.1. [Instalación](01.1.md) 3 | - 1.2. [$GOPATH y espacio de trabajo](01.2.md) 4 | - 1.3. [Comandos con Go](01.3.md) 5 | - 1.4. [Herramientas de desarrollo para Go](01.4.md) 6 | - 1.5. [Resumen](01.5.md) 7 | - 2.[Conocimientos básicos sobre Go](02.0.md) 8 | - 2.1. ["Hello, Go"](02.1.md) 9 | - 2.2. [Principios de Go](02.2.md) 10 | - 2.3. [Sentencias de control y funciones](02.3.md) 11 | - 2.4. [struct](02.4.md) 12 | - 2.5. [Orientado a objetos](02.5.md) 13 | - 2.6. [interfaces](02.6.md) 14 | - 2.7. [Concurrencia](02.7.md) 15 | - 2.8. [Resumen](02.8.md) 16 | - 3.[Conocimientos básicos sobre la Web](03.0.md) 17 | - 3.1. [Principios para el trabajo en la Web](03.1.md) 18 | - 3.2. [Armando un servidor web sencillo](03.2.md) 19 | - 3.3. [Como trabaja Go con la web](03.3.md) 20 | - 3.4. [Obteniendo el paquete http](03.4.md) 21 | - 3.5. [Resumen](03.5.md) 22 | - 4.[Formulario de entrada de los usuario](04.0.md) 23 | - 4.1. [Procesando la entrada de los formularios](04.1.md) 24 | - 4.2. [Verificando las entradas](04.2.md) 25 | - 4.3. [Cross site scripting](04.3.md) 26 | - 4.4. [Envíos duplicados](04.4.md) 27 | - 4.5. [Subida de archivos](04.5.md) 28 | - 4.6. [Resumen](04.6.md) 29 | - 5.[Base de datos](05.0.md) 30 | - 5.1. [database/sql interfaz](05.1.md) 31 | - 5.2. [MySQL](05.2.md) 32 | - 5.3. [SQLite](05.3.md) 33 | - 5.4. [PostgreSQL](05.4.md) 34 | - 5.5. [Desarrollo de un ORM basado en beedb](05.5.md) 35 | - 5.6. [Base de datos NoSQL](05.6.md) 36 | - 5.7. [Resumen](05.7.md) 37 | - 6.[Almacenamiento de datos y sesiones](06.0.md) 38 | - 6.1. [Sesiones y cookies](06.1.md) 39 | - 6.2. [Como usar sesiones en Go](06.2.md) 40 | - 6.3. [Almacenar sesiones](06.3.md) 41 | - 6.4. [Prevenir hijack de la sesión](06.4.md) 42 | - 6.5. [Resumen](06.5.md) 43 | - 7.[Archivos de texto](07.0.md) 44 | - 7.1. [XML](07.1.md) 45 | - 7.2. [JSON](07.2.md) 46 | - 7.3. [Regexp](07.3.md) 47 | - 7.4. [Plantillas](07.4.md) 48 | - 7.5. [Archivos](07.5.md) 49 | - 7.6. [Strings](07.6.md) 50 | - 7.7. [Resumen](07.7.md) 51 | - 8.[Servicios Web](08.0.md) 52 | - 8.1. [Sockets](08.1.md) 53 | - 8.2. [WebSocket](08.2.md) 54 | - 8.3. [REST](08.3.md) 55 | - 8.4. [RPC](08.4.md) 56 | - 8.5. [Resumen](08.5.md) 57 | - 9.[Seguridad y encriptación](09.0.md) 58 | - 9.1. [ataques CSRF](09.1.md) 59 | - 9.2. [Filtro de entrada](09.2.md) 60 | - 9.3. [ataques XSS](09.3.md) 61 | - 9.4. [inyección de SQL](09.4.md) 62 | - 9.5. [Almacenamiento de contraseñas](09.5.md) 63 | - 9.6. [Encriptar y desencryptar datos](09.6.md) 64 | - 9.7. [Resumen](09.7.md) 65 | - 10.[Internacionalización y localización](10.0.md) 66 | - 10.1 [Zonas horarias](10.1.md) 67 | - 10.2 [Recursos traducidos](10.2.md) 68 | - 10.3 [Sitios internacionales](10.3.md) 69 | - 10.4 [Resumen](10.4.md) 70 | - 11.[Manejo de errores, debug y test](11.0.md) 71 | - 11.1. [Manejo de errores](11.1.md) 72 | - 11.2. [Debug usando GDB](11.2.md) 73 | - 11.3. [Escribiendo tests](11.3.md) 74 | - 11.4. [Resumen](11.4.md) 75 | - 12.[Despliegue y mantenimiento](12.0.md) 76 | - 12.1. [Logs](12.1.md) 77 | - 12.2. [Errores](12.2.md) 78 | - 12.3. [Despliegue](12.3.md) 79 | - 12.4. [Backups y recuperación](12.4.md) 80 | - 12.5. [Resumen](12.5.md) 81 | - 13.[Construyendo un framework web](13.0.md) 82 | - 13.1. [Programación del proyecto](13.1.md) 83 | - 13.2. [Personalizando routers](13.2.md) 84 | - 13.3. [Diseñando controladores](13.3.md) 85 | - 13.4. [Logs y configuración](13.4.md) 86 | - 13.5. [Add, delete and update blogs](13.5.md) 87 | - 13.6. [Resumen](13.6.md) 88 | - 14.[Desarrollando un framework web](14.0.md) 89 | - 14.1. [Archivos estáticos](14.1.md) 90 | - 14.2. [Sesiones](14.2.md) 91 | - 14.3. [Formularios](14.3.md) 92 | - 14.4. [Validación de usuarios](14.4.md) 93 | - 14.5. [Soporte para multi-lenguaje](14.5.md) 94 | - 14.6. [pprof](14.6.md) 95 | - 14.7. [Resumen](14.7.md) 96 | - Apéndice A [Referencias](ref.md) 97 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Comentario: 2 | Se va a dar comienzo a la traducción al español del siguiente libro: 3 | https://github.com/Unknwon/build-web-application-with-golang_EN 4 | Este comentario se va a mantener, hasta que se haya finalizado la traducción. 5 | 6 | ## Aportar a la traducción: 7 | 8 | Si usted desea aportar a esta traducción siga las [siguientes instrucciones](./eBook/contribute.md) 9 | 10 | ***Construyendo aplicaciones web con Golang*** 11 | ======================================= 12 | ### ***Comentario del traductor*** 13 | 14 | Esta es la versión en español de [《Go Web编程》](https://github.com/astaxie/build-web-application-with-golang), la versión original fue escrita por [AstaXie](https://github.com/astaxie) y esta es traducida por [jackgris](https://github.com/jackgris).Con la contribución de [carlosjml4](https://github.com/carlosjml4). 15 | 16 | Este libro trata sobre como crear aplicaciones web en Go. En los primeros capítulos del libro, el autor va a repasar algunos conocimientos básicos sobre Go. Sin embargo, para obtener una mejor experiencia en la lectura, usted debería tener los conocimientos básicos sobre el lenguaje Go y sobre los conceptos de una aplicación web. Si usted es completamente nuevo en el mundo de la programación, este libro no tiene en cuenta proporcionar el material introductorio suficiente para comenzar. 17 | 18 | Si algo no quedo claro en cuestiones de redacción o del lenguaje. No dude en pedirme una mejor traducción. 19 | 20 | ### Objetivo 21 | 22 | Como estoy interesado en el desarrollo de aplicaciones web, eh usado mi tiempo libre para escribir este libro como una versión de libre ('open source'). Esto no significa que tenga grandes capacidades en la construcción de aplicaciones web, simplemente me gustaría compartir lo que eh realizado con Go en la construcción de aplicaciones web. 23 | 24 | - Para los que estén trabajando con PHP/Python/Ruby, ustedes van a aprender como construir aplicaciones web con Go. 25 | - Para los que estén trabajando con C/C++, ustedes aprenderán como funciona la web. 26 | 27 | Creo que el propósito de estudiar es compartir con los demás. El momento mas feliz de mi vida es compartir todo lo que se con otras personas. 28 | 29 | ### Donaciones 30 | 31 | Si te gusta este libro, usted puede seguir este [link](https://me.alipay.com/astaxie) para realizar la donación al autor original, para ayudarlo a escribir mas libros con mejor, mas útil y mas interesante contenido. 32 | 33 | ### Intercambio para el aprendizaje de Go 34 | 35 | Si sabes lo que es QQ, podes unirte al grupo 259316004. Si no, seguí este [link](http://download.imqq.com/download.shtml) para ver mas detalles. Ademas, podes unirte a nuestro [foro](http://bbs.beego.me). 36 | 37 | ### Agradecimientos 38 | 39 | En primer lugar, debo agradecer a aquellas personas que son miembros de Golang-China en el grupo 102319854 de QQ, todos ellos son muy agradables y muy predispuestos a ayudar. A continuación, debo agradecer a las siguientes personas que fueron de gran ayuda cuando estaba escribiendo este libro. 40 | 41 | - [四月份平民 April Citizen](https://plus.google.com/110445767383269817959) (revisión de código) 42 | - [洪瑞琦 Hong Ruiqi](https://github.com/hongruiqi) (revisión de código) 43 | - [边 疆 BianJiang](https://github.com/border) (escribió las configuraciones de Vim y Emacs para el desarrollo en Go) 44 | - [欧林猫 Oling Cat](https://github.com/OlingCat)(revisión de código) 45 | - [吴文磊 Wenlei Wu](mailto:spadesacn@gmail.com)( proporcionó algunas imágenes) 46 | - [北极星 Polaris](https://github.com/polaris1119)(revisión completa del libro) 47 | - [雨 痕 Rain Trail](https://github.com/qyuhen)(revisión de los capítulos 2 y 3) 48 | 49 | ### Licencia 50 | 51 | Este libro se encuentra bajo la licencia [CC BY-SA 3.0 License](http://creativecommons.org/licenses/by-sa/3.0/), 52 | el código es licenciado bajo [BSD 3-Clause License](), a menos que se especifique lo contrario. 53 | 54 | ### Vamos a comenzar 55 | 56 | [Indice](./eBook/preface.md) 57 | -------------------------------------------------------------------------------- /eBook/05.3.md: -------------------------------------------------------------------------------- 1 | # 5.3 SQLite 2 | 3 | SQLite es una base de datos relacional, open source, tiene su propio contenedor, zero-configuration (no necesita configuración) y con un motor de base de datos con soporte para respaldo. Tiene como característicamente ser muy portable, sencilla de usar, compacta, eficiente y segura. En la mayoría de los casos, únicamente va a necesitar el archivo binaria de SQLite para crearla, conectar y operar la base de datos. Si estas buscando una solución de una base de datos embebida, vale la pena considerar SQLite. Podría decir que SQLite es una versión open source de Access. 4 | 5 | ## Drivers de SQLite 6 | 7 | Hay muchos drivers de base de datos para SQLite en Go, pero mucho de ellos no soportan la interfaz estándar `database/sql`. 8 | 9 | - [https://github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) soporta `database/sql`, basado en cgo. 10 | - [https://github.com/feyeleanor/gosqlite3](https://github.com/feyeleanor/gosqlite3) no soporta `database/sql`, basado en cgo. 11 | - [https://github.com/phf/go-sqlite3](https://github.com/phf/go-sqlite3) no soporta `database/sql`, basado en cgo. 12 | 13 | El primer driver es el único que soporta la interfaz estándar `database/sql` en los drivers de SQLite, por eso utilice este para mi proyecto y va a ser sencillo migrar el código en el futuro. 14 | 15 | ## Ejemplos 16 | 17 | El SQL para crearla es el siguiente: 18 | 19 | ```sql 20 | CREATE TABLE `userinfo` ( 21 | `uid` INTEGER PRIMARY KEY AUTOINCREMENT, 22 | `username` VARCHAR(64) NULL, 23 | `departname` VARCHAR(64) NULL, 24 | `created` DATE NULL 25 | ); 26 | ``` 27 | 28 | Un ejemplo: 29 | 30 | ```go 31 | package main 32 | 33 | import ( 34 | "database/sql" 35 | "fmt" 36 | _ "github.com/mattn/go-sqlite3" 37 | ) 38 | 39 | func main() { 40 | db, err := sql.Open("sqlite3", "./foo.db") 41 | checkErr(err) 42 | 43 | // insert 44 | stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, created) values(?,?,?)") 45 | checkErr(err) 46 | 47 | res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09") 48 | checkErr(err) 49 | 50 | id, err := res.LastInsertId() 51 | checkErr(err) 52 | 53 | fmt.Println(id) 54 | // update 55 | stmt, err = db.Prepare("update userinfo set username=? where uid=?") 56 | checkErr(err) 57 | 58 | res, err = stmt.Exec("astaxieupdate", id) 59 | checkErr(err) 60 | 61 | affect, err := res.RowsAffected() 62 | checkErr(err) 63 | 64 | fmt.Println(affect) 65 | 66 | // query 67 | rows, err := db.Query("SELECT * FROM userinfo") 68 | checkErr(err) 69 | 70 | for rows.Next() { 71 | var uid int 72 | var username string 73 | var department string 74 | var created string 75 | err = rows.Scan(&uid, &username, &department, &created) 76 | checkErr(err) 77 | fmt.Println(uid) 78 | fmt.Println(username) 79 | fmt.Println(department) 80 | fmt.Println(created) 81 | } 82 | 83 | // delete 84 | stmt, err = db.Prepare("delete from userinfo where uid=?") 85 | checkErr(err) 86 | 87 | res, err = stmt.Exec(id) 88 | checkErr(err) 89 | 90 | affect, err = res.RowsAffected() 91 | checkErr(err) 92 | 93 | fmt.Println(affect) 94 | 95 | db.Close() 96 | 97 | } 98 | 99 | func checkErr(err error) { 100 | if err != nil { 101 | panic(err) 102 | } 103 | } 104 | ``` 105 | 106 | Puede notar que el código es casi igual al de la sección anterior, y que sólo cambió el nombre del controlador registrado, y la llamada a `sql.Open` para conectarse a SQLite de una manera diferente. 107 | Hay una herramienta para la gestión de SQLite disponible: [http://sqliteadmin.orbmu2k.de/](http://sqliteadmin.orbmu2k.de/) 108 | 109 | ## Enlaces 110 | 111 | - [Indice](preface.md) 112 | - Sección anterior: [MySQL](05.2.md) 113 | - Siguiente sección: [PostgreSQL](05.4.md) -------------------------------------------------------------------------------- /eBook/14.6.md: -------------------------------------------------------------------------------- 1 | # 14.6 pprof 2 | 3 | El lenguaje Go tiene un gran diseño es la biblioteca estándar con herramientas de monitorización del rendimiento del código, hay paquetes en dos lugares: 4 | 5 | net/http/pprof 6 | 7 | runtime/pprof 8 | 9 | In fact, `net/http/pprof` in just using `runtime/pprof` package for packaging a bit, and exposed on the http port 10 | 11 | ## Beego pprof soporte 12 | 13 | Actualmente beego marco agrega pprof, esta función no está activada de forma predeterminada, si usted necesita para poner a prueba el rendimiento, ver el goroutine ejecución dicha información, de hecho, el paquete por defecto de Go "net / http / pprof" ya cuenta con esta función y, si Go forma de acuerdo con el Web predeterminado, puede utilizar el valor predeterminado, sino porque beego función ServHTTP reenvasado, así que si usted no puede abrir el defecto incluye esta característica, por lo que la necesidad de una reforma interna beego apoyo pprof. 14 | 15 | En primer lugar, en función de beego.Run automáticamente en función de si el paquete de rendimiento de carga variable 16 | 17 | - En primer lugar, en función de beego.Run automáticamente en función de si el paquete de rendimiento de carga variableck 18 | 19 | if PprofOn { 20 | BeeApp.RegisterController(`/debug/pprof`, &ProfController{}) 21 | BeeApp.RegisterController(`/debug/pprof/:pp([\w]+)`, &ProfController{}) 22 | } 23 | 24 | - Diseño ProfConterller 25 | 26 | package beego 27 | 28 | import ( 29 | "net/http/pprof" 30 | ) 31 | 32 | type ProfController struct { 33 | Controller 34 | } 35 | 36 | func (this *ProfController) Get() { 37 | switch this.Ctx.Params[":pp"] { 38 | default: 39 | pprof.Index(this.Ctx.ResponseWriter, this.Ctx.Request) 40 | case "": 41 | pprof.Index(this.Ctx.ResponseWriter, this.Ctx.Request) 42 | case "cmdline": 43 | pprof.Cmdline(this.Ctx.ResponseWriter, this.Ctx.Request) 44 | case "profile": 45 | pprof.Profile(this.Ctx.ResponseWriter, this.Ctx.Request) 46 | case "symbol": 47 | pprof.Symbol(this.Ctx.ResponseWriter, this.Ctx.Request) 48 | } 49 | this.Ctx.ResponseWriter.WriteHeader(200) 50 | } 51 | 52 | 53 | ## Primeros pasos 54 | 55 | A través del diseño anterior, puede utilizar el siguiente código para abrir pprof: 56 | 57 | beego.PprofOn = true 58 | 59 | A continuación, puede abrir en un navegador la siguiente dirección URL para ver la siguiente interfaz: 60 | 61 | ![](images/14.6.pprof.png?raw=true) 62 | 63 | Figure 14.7 current system goroutine, heap, thread information 64 | 65 | Click goroutine podemos ver una gran cantidad de información detallada: 66 | 67 | ![](images/14.6.pprof2.png?raw=true) 68 | 69 | Figure 14.8 shows the current goroutine details 70 | 71 | También podemos conseguir más detalles de la información de la línea de comandos 72 | 73 | go tool pprof http://localhost:8080/debug/pprof/profile 74 | 75 | Esta vez, el programa entrará en el tiempo de recogida de perfil de 30 segundos, tiempo durante el cual desesperadamente para actualizar la página en el navegador, tratar de hacer que los datos de rendimiento de uso de la CPU. 76 | 77 | (pprof) top10 78 | 79 | Total: 3 samples 80 | 81 | 1 33.3% 33.3% 1 33.3% MHeap_AllocLocked 82 | 83 | 1 33.3% 66.7% 1 33.3% os/exec.(*Cmd).closeDescriptors 84 | 85 | 1 33.3% 100.0% 1 33.3% runtime.sigprocmask 86 | 87 | 0 0.0% 100.0% 1 33.3% MCentral_Grow 88 | 89 | 0 0.0% 100.0% 2 66.7% main.Compile 90 | 91 | 0 0.0% 100.0% 2 66.7% main.compile 92 | 93 | 0 0.0% 100.0% 2 66.7% main.run 94 | 95 | 0 0.0% 100.0% 1 33.3% makeslice1 96 | 97 | 0 0.0% 100.0% 2 66.7% net/http.(*ServeMux).ServeHTTP 98 | 99 | 0 0.0% 100.0% 2 66.7% net/http.(*conn).serve 100 | 101 | (pprof)web 102 | 103 | ![](images/14.6.pprof3.png?raw=true) 104 | 105 | Figure 14.9 shows the execution flow of information 106 | 107 | ## Links 108 | 109 | - [Directory](preface.md) 110 | - Previous section: [Multi-language support](14.5.md) 111 | - Next section: [Summary](14.7.md) 112 | 113 | -------------------------------------------------------------------------------- /eBook/14.2.md: -------------------------------------------------------------------------------- 1 | # 14.2 Sesión 2 | 3 | Capítulo VI, cuando vimos cómo utilizar la sesión lenguaje Go, también logró un sessionManger, beego marco basado SessionManager para lograr un cómodo manejo de las funciones de la sesión. 4 | 5 | ## Integración Sesión 6 | 7 | beego principalmente en las siguientes variables globales para controlar el manejo de sesión: 8 | 9 | // En relación con la sesión 10 | SessionOn bool // si desea abrir el módulo de sesión, el valor predeterminado no está abierto 11 | SessionProvider string // sesión proporcionada, el valor predeterminado es SessionManager apoyó memoria 12 | SessionName string // nombre del cliente guardada en las cookies 13 | SessionGCMaxLifetime int64 // cookies validity 14 | 15 | GlobalSessions *session.Manager// controlador de la sesión / global 16 | 17 | Por supuesto, los valores por encima de estas variables deben ser inicializado, también puede seguir el código para que coincida con el archivo de configuración para establecer estos valores: 18 | 19 | if ar, err := AppConfig.Bool("sessionon"); err != nil { 20 | SessionOn = false 21 | } else { 22 | SessionOn = ar 23 | } 24 | if ar := AppConfig.String("sessionprovider"); ar == "" { 25 | SessionProvider = "memory" 26 | } else { 27 | SessionProvider = ar 28 | } 29 | if ar := AppConfig.String("sessionname"); ar == "" { 30 | SessionName = "beegosessionID" 31 | } else { 32 | SessionName = ar 33 | } 34 | if ar, err := AppConfig.Int("sessiongcmaxlifetime"); err != nil && ar != 0 { 35 | int64val, _ := strconv.ParseInt(strconv.Itoa(ar), 10, 64) 36 | SessionGCMaxLifetime = int64val 37 | } else { 38 | SessionGCMaxLifetime = 3600 39 | } 40 | 41 | In beego.Run funcionar para agregar el siguiente código: 42 | 43 | if SessionOn { 44 | GlobalSessions, _ = session.NewManager(SessionProvider, SessionName, SessionGCMaxLifetime) 45 | go GlobalSessions.GC() 46 | } 47 | 48 | Mientras SessionOn establece en true, entonces se abrirá la sesión con la función por defecto para abrir un goroutine independiente para manejar la sesión. 49 | 50 | Con el fin de facilitar nuestra costumbre Controller rápidamente utilizando la sesión, el autor beego.Controller proporciona los siguientes métodos:: 51 | 52 | func (c *Controller) StartSession() (sess session.Session) { 53 | sess = GlobalSessions.SessionStart(c.Ctx.ResponseWriter, c.Ctx.Request) 54 | return 55 | } 56 | 57 | ## Sesión usando 58 | 59 | A través del código anterior podemos ver, beego marco simplemente hereda la función de sesión, entonces cómo usarlo en su proyecto? 60 | 61 | En primer lugar, tenemos que aplicar la sesión principal abierta de entrada: 62 | 63 | beego.SessionOn = true 64 | 65 | 66 | Podemos entonces el método correspondiente en el controlador para usar la sesión de la siguiente manera: 67 | 68 | func (this *MainController) Get() { 69 | var intcount int 70 | sess := this.StartSession() 71 | count := sess.Get("count") 72 | if count == nil { 73 | intcount = 0 74 | } else { 75 | intcount = count.(int) 76 | } 77 | intcount = intcount + 1 78 | sess.Set("count", intcount) 79 | this.Data["Username"] = "astaxie" 80 | this.Data["Email"] = "astaxie@gmail.com" 81 | this.Data["Count"] = intcount 82 | this.TplNames = "index.tpl" 83 | } 84 | 85 | El código anterior muestra cómo utilizar la sesión de la lógica de control, dividida principalmente en dos pasos: 86 | 87 | 1. Obtenga objeto de sesión 88 | 89 | // Get the object, similar in PHP session_start() 90 | sess:= this.StartSession() 91 | 92 | 2. utilizar la sesión para el funcionamiento general de valor de la sesión 93 | 94 | // Get the session values , similar in PHP $ _SESSION ["count"] 95 | sess.Get("count") 96 | 97 | // Set the session value 98 | sess.Set("count", intcount) 99 | 100 | Como puede verse a partir del marco de código beego por encima de aplicaciones basadas desarrollaron utilizando la sesión bastante fácil, básicamente, y PHP para llamar a `session_start()` similar. 101 | 102 | ## Links 103 | 104 | - [Directory](preface.md) 105 | - Previous section: [Static files](14.1.md) 106 | - Next section: [Form](14.3.md) 107 | -------------------------------------------------------------------------------- /eBook/07.5.md: -------------------------------------------------------------------------------- 1 | # 7.5 Archivos 2 | 3 | El archivo se debe-tener como un objeto unico en cada dispositivo informático y tambien en aplicaciones web se tiene mucho uso. En esta sección, vamos a aprender a manejar archivos en Go. 4 | 5 | ## DirectoriosDirectories 6 | 7 | La mayor parte de las funciones de las operaciones de archivos estan en el package `os`, he aquí algunas funciones sobre directorios: 8 | 9 | - func Mkdir(name string, perm FileMode) error 10 | 11 | Crear directorio con `name`, `perm`, 0777. 12 | 13 | - func MkdirAll(path string, perm FileMode) error 14 | 15 | Crear varios directorios de acuerdo al `path`, como `astaxie/test1/test2`. 16 | 17 | - func Remove(name string) error 18 | 19 | Remueve el directorio `name`, devuelve error si no es directorio o no está vacío. 20 | 21 | - func RemoveAll(path string) error 22 | 23 | Eliminar varios directorios de acuerdo `path` , no se borrará si camino es un camino único. 24 | 25 | Codigo de ejemplo: 26 | 27 | package main 28 | 29 | import ( 30 | "fmt" 31 | "os" 32 | ) 33 | 34 | func main() { 35 | os.Mkdir("astaxie", 0777) 36 | os.MkdirAll("astaxie/test1/test2", 0777) 37 | err := os.Remove("astaxie") 38 | if err != nil { 39 | fmt.Println(err) 40 | } 41 | os.RemoveAll("astaxie") 42 | } 43 | 44 | ## Archivos 45 | 46 | ### Crear y abrir archivos 47 | 48 | Dos funciones para crear los archivos: 49 | 50 | - func Create(name string) (file *File, err Error) 51 | 52 | Crear un archivo con el `name` y devolver un objeto de archivo con el permiso 0666 de lectura y escritura 53 | 54 | - func NewFile(fd uintptr, name string) *File 55 | 56 | Crear un archivo y devolver un objeto de archivo. 57 | 58 | 59 | Dos funciones para abrir archivos: 60 | 61 | - func Open(name string) (file *File, err Error) 62 | 63 | Open file with `name` con el permiso de sólo lectura, y llama a `OpenFile` con guion bajo. 64 | 65 | - func OpenFile(name string, flag int, perm uint32) (file *File, err Error) 66 | 67 | Open file with `name`, `flag` es el modo abierto como read-only, read-write, `perm` es el permiso. 68 | 69 | ### Escribir archivos 70 | 71 | Funciones para la escritura de archivos: 72 | 73 | - func (file *File) Write(b []byte) (n int, err Error) 74 | 75 | Escribe byte tipo de contenido en un archivo. 76 | 77 | - func (file *File) WriteAt(b []byte, off int64) (n int, err Error) 78 | 79 | Escribe byte tipo de contenido a determinada posición de archivo. 80 | 81 | - func (file *File) WriteString(s string) (ret int, err Error) 82 | 83 | Escribe cadena en el archivo. 84 | 85 | Code sample: 86 | 87 | package main 88 | 89 | import ( 90 | "fmt" 91 | "os" 92 | ) 93 | 94 | func main() { 95 | userFile := "astaxie.txt" 96 | fout, err := os.Create(userFile) 97 | if err != nil { 98 | fmt.Println(userFile, err) 99 | return 100 | } 101 | defer fout.Close() 102 | for i := 0; i < 10; i++ { 103 | fout.WriteString("Just a test!\r\n") 104 | fout.Write([]byte("Just a test!\r\n")) 105 | } 106 | } 107 | 108 | ### Leer los archivos 109 | 110 | Funciones para leer los archivos 111 | 112 | - func (file *File) Read(b []byte) (n int, err Error) 113 | 114 | Lee datos de `b`. 115 | 116 | - func (file *File) ReadAt(b []byte, off int64) (n int, err Error) 117 | 118 | Lee datos en posicion `off` to `b`. 119 | 120 | Code sample: 121 | 122 | package main 123 | 124 | import ( 125 | "fmt" 126 | "os" 127 | ) 128 | 129 | func main() { 130 | userFile := "asatxie.txt" 131 | fl, err := os.Open(userFile) 132 | if err != nil { 133 | fmt.Println(userFile, err) 134 | return 135 | } 136 | defer fl.Close() 137 | buf := make([]byte, 1024) 138 | for { 139 | n, _ := fl.Read(buf) 140 | if 0 == n { 141 | break 142 | } 143 | os.Stdout.Write(buf[:n]) 144 | } 145 | } 146 | 147 | ### Eliminar archivos 148 | 149 | Go utiliza la misma función para eliminar archivos y directorios: 150 | 151 | - func Remove(name string) Error 152 | 153 | Eliminar archivo o directorio con `name`.( ***`name`termina con `/` directorio*** ) 154 | 155 | ## Links 156 | 157 | - [Directory](preface.md) 158 | - Previous section: [Templates](07.4.md) 159 | - Next section: [Strings](07.6.md) 160 | -------------------------------------------------------------------------------- /eBook/14.1.md: -------------------------------------------------------------------------------- 1 | # 14.1 Static files 2 | 3 | Los archivos estáticos 4 | Como ya hemos hablado de cómo hacer frente a los archivos estáticos, este apartado vamos a detallar cómo configurar y utilizar en beego archivos estáticos en el interior. Para entonces introducir un HTML de código abierto framework bootstrap css de arranque, sin un montón de trabajo de diseño podemos permitirá crear rápidamente un sitio hermoso. 5 | 6 | ## Beego archivos estáticos y los ajustes para lograr 7 | 8 | Paquete net / http Go proporciona un archivo estático que sirve, ServeFile y servidorArchivos otras funciones. beego procesamiento de archivo estático se maneja sobre la base de esta capa, la aplicación específica es la siguiente: 9 | 10 | //Servidor de archivos estáticos 11 | for prefix, staticDir := range StaticDir { 12 | if strings.HasPrefix(r.URL.Path, prefix) { 13 | file := staticDir + r.URL.Path[len(prefix):] 14 | http.ServeFile(w, r, file) 15 | w.started = true 16 | return 17 | } 18 | } 19 | 20 | StaticDir se almacena dentro de la URL correspondiente corresponde a un directorio de archivo estático, por lo que manejar peticiones de URL cuando la solicitud sólo necesita determinar si la dirección correspondiente al comienzo del proceso contiene el URL estática, si se incluye en el uso http.ServeFile prestacion de servicios. 21 | 22 | Examples: 23 | 24 | beego.StaticDir["/asset"] = "/static" 25 | 26 | Example. Entonces la solicitud url `http://www.beego.me/asset/bootstrap.css` solicitara `/static/bootstrap.css` para el cliente. 27 | 28 | ## Bootstrap integration 29 | 30 | Bootstrap is Twitter puso en marcha un conjunto de herramientas de código abierto para el desarrollo de aplicaciones para usuario. Para los desarrolladores, Manos a la Obra es el rápido desarrollo de los mejores front-end de aplicaciones web toolkit. Se trata de una colección de CSS y HTML, se utiliza el último estándar de HTML5, para el desarrollo de su Web ofrece elegantes tipografía, formas, botones, tablas, cuadrículas, sistemas, etc 31 | 32 | - Componentes 33 | Bootstrap contiene una gran cantidad de componentes Web, de acuerdo con estos componentes, puede crear rápidamente un hermoso sitio web, totalmente funcional. Que incluye los siguientes componentes: menús desplegables, botones, grupos, botones menús desplegables, navegación, barra de navegación, el pan rallado, la paginación, el diseño, miniaturas, de diálogo de advertencia, barras de progreso, y otros objetos multimedia 34 | 35 | - JavaScript plugin de Bootstrap viene con 13 jQuery plug-ins para el Bootstrap un componente da "vida". Incluyendo: diálogo modal, tab, barras de desplazamiento, cuadro de pop-up y así sucesivamente. 36 | 37 | - Personaliza tu propia Bootstrap código marco puede modificar todas las variables de estilo CSS, en función de sus propias necesidades código de recorte. 38 | 39 | ![](images/14.1.bootstrap.png?raw=true) 40 | 41 | Figure 14.1 bootstrap site 42 | 43 | Next, we use the bootstrap into beego frame inside, quickly create a beautiful site. 44 | 45 | 1. En primer lugar para descargar el directorio de arranque en nuestro directorio del proyecto, nombrado como estática, como se muestra en la captura de pantalla 46 | 47 | ![](images/14.1.bootstrap2.png?raw=true) 48 | 49 | Figure 14.2 Project static file directory structure 50 | 51 | 2. Debido beego valores predeterminados establecidos StaticDir, así que si su directorio de archivos estático es estático, entonces no es necesario ir más lejos: 52 | 53 | StaticDir["/static"] = "static" 54 | 55 | 3. plantillas utilizan la siguiente dirección en él: 56 | 57 | // css file 58 | 59 | 60 | // js file 61 | 62 | 63 | // Picture files 64 | 65 | 66 | Lo anterior se puede lograr para arrancar en beego en el pasado, como se demuestra en la figura es la integración de la feria se produjo después de las representaciones: 67 | 68 | ![](images/14.1.bootstrap3.png?raw=true) 69 | 70 | Figure 14.3 Construction site interface based bootstrap 71 | 72 | Estas plantillas y formatos oficiales de arranque tiene que ofrecer no se repetirá aquí pegar código, podemos iniciarla en el sitio web oficial para aprender a escribir las plantillas. 73 | 74 | ## Links 75 | 76 | - [Directory](preface.md) 77 | - Previous section: [Develop web framework](14.0.md) 78 | - Next section: [Session](14.2.md) 79 | -------------------------------------------------------------------------------- /eBook/05.4.md: -------------------------------------------------------------------------------- 1 | # 5.4 PostgreSQL 2 | 3 | PostgreSQL es un sistema gestor de bases de datos objeto-relacional disponible para muchas plataformas, incluyendo Linux, FreeBSD, Solaris, Microsoft Windows y Mac OS X. Está liberado bajo una licencia de estilo MIT, y es por lo tanto software libre de código abierto. Es más grande que MySQL, pues está diseñada para un uso empresarial como Oracle. Así que es una buena opción usar PostgreSQL en proyectos empresariales. 4 | 5 | ## Drivers de PostgreSQL 6 | 7 | Hay muchos drivers para la base de datos PostgreSQL, y tres de ellos son los siguientes: 8 | 9 | - [https://github.com/bmizerany/pq](https://github.com/bmizerany/pq) suporta `database/sql`, puro código Go. 10 | - [https://github.com/jbarham/gopgsqldriver](https://github.com/jbarham/gopgsqldriver) suporta `database/sql`, puro código Go. 11 | - [https://github.com/lxn/go-pgsql](https://github.com/lxn/go-pgsql) suporta `database/sql`, puro código Go. 12 | 13 | Voy a utilizar el primero para los siguientes ejemplos. 14 | 15 | ## Ejemplos 16 | 17 | Creamos el SQL de la siguiente forma: 18 | 19 | ```sql 20 | CREATE TABLE userinfo 21 | ( 22 | uid serial NOT NULL, 23 | username character varying(100) NOT NULL, 24 | departname character varying(500) NOT NULL, 25 | Created date, 26 | CONSTRAINT userinfo_pkey PRIMARY KEY (uid) 27 | ) 28 | WITH (OIDS=FALSE); 29 | ``` 30 | 31 | Un ejemplo: 32 | 33 | ```go 34 | package main 35 | 36 | import ( 37 | "database/sql" 38 | "fmt" 39 | _ "github.com/bmizerany/pq" 40 | "time" 41 | ) 42 | 43 | const ( 44 | DB_USER = "postgres" 45 | DB_PASSWORD = "postgres" 46 | DB_NAME = "test" 47 | ) 48 | 49 | func main() { 50 | dbinfo := fmt.Sprintf("user=%s password=%s dbname=%s sslmode=disable", 51 | DB_USER, DB_PASSWORD, DB_NAME) 52 | db, err := sql.Open("postgres", dbinfo) 53 | checkErr(err) 54 | defer db.Close() 55 | 56 | fmt.Println("# Inserting values") 57 | 58 | var lastInsertId int 59 | err = db.QueryRow("INSERT INTO userinfo(username,departname,created) VALUES($1,$2,$3) returning uid;", "astaxie", "研发部门", "2012-12-09").Scan(&lastInsertId) 60 | checkErr(err) 61 | fmt.Println("last inserted id =", lastInsertId) 62 | 63 | fmt.Println("# Updating") 64 | stmt, err := db.Prepare("update userinfo set username=$1 where uid=$2") 65 | checkErr(err) 66 | 67 | res, err := stmt.Exec("astaxieupdate", lastInsertId) 68 | checkErr(err) 69 | 70 | affect, err := res.RowsAffected() 71 | checkErr(err) 72 | 73 | fmt.Println(affect, "rows changed") 74 | 75 | fmt.Println("# Querying") 76 | rows, err := db.Query("SELECT * FROM userinfo") 77 | checkErr(err) 78 | 79 | for rows.Next() { 80 | var uid int 81 | var username string 82 | var department string 83 | var created time.Time 84 | err = rows.Scan(&uid, &username, &department, &created) 85 | checkErr(err) 86 | fmt.Println("uid | username | department | created ") 87 | fmt.Printf("%3v | %8v | %6v | %6v\n", uid, username, department, created) 88 | } 89 | 90 | fmt.Println("# Deleting") 91 | stmt, err = db.Prepare("delete from userinfo where uid=$1") 92 | checkErr(err) 93 | 94 | res, err = stmt.Exec(lastInsertId) 95 | checkErr(err) 96 | 97 | affect, err = res.RowsAffected() 98 | checkErr(err) 99 | 100 | fmt.Println(affect, "rows changed") 101 | } 102 | 103 | func checkErr(err error) { 104 | if err != nil { 105 | panic(err) 106 | } 107 | } 108 | ``` 109 | 110 | Tenga en cuenta que PostgreSQL usa formato como `$1,$2` en vez de `?` como en MySQL, y tiene un formato diferente de DSN en `sql.Open`. 111 | Otra cosa es que Postgres no soporta `sql.Result.LastInsertId()`. 112 | Por eso en vez de esto, 113 | 114 | ```go 115 | stmt, err := db.Prepare("INSERT INTO userinfo(username,departname,created) VALUES($1,$2,$3);") 116 | res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09") 117 | fmt.Println(res.LastInsertId()) 118 | ``` 119 | 120 | Usamos esto `db.QueryRow()` y esto `.Scan()` para obtener el valor del ultimo id insertado. 121 | 122 | ```go 123 | err = db.QueryRow("INSERT INTO TABLE_NAME values($1) returning uid;", VALUE1").Scan(&lastInsertId) 124 | fmt.Println(lastInsertId) 125 | ``` 126 | 127 | ## Enlaces 128 | 129 | - [Indice](preface.md) 130 | - Sección anterior: [SQLite](05.3.md) 131 | - Siguiente sección: [Desarrollo de un ORM basado en beedb](05.5.md) 132 | -------------------------------------------------------------------------------- /eBook/05.6.md: -------------------------------------------------------------------------------- 1 | # 5.6 NoSQL database 2 | 3 | Una base de datos NoSQL proporciona un mecanismo para el almacenamiento y recuperación de datos que utilizan modelos de consistencia más debiles que las base de datos relacionales para lograr una escala más horizontal y una mayor disponibilidad. Algunos autores se refieren a ellas como "No sólo SQL" para enfatizar que algunos sistemas NoSQL permiten un lenguaje de consulta similar al SQL para ser utilizado. 4 | 5 | Como el lenguaje C de siglo 21, Go tiene un buen soporte para bases de datos NoSQL, y las bases de datos NoSQL más populares incluyendo redis, mongoDB, Cassandra y Membase. 6 | 7 | ## Redis 8 | 9 | Redis es un sistema de almacenamiento clave-valor como Memcached, soporta string, list, set y zset(set ordenado) ya que evalua tipos. 10 | 11 | Acá hay algunos drivers de base de datos de Go para redis: 12 | 13 | - [https://github.com/alphazero/Go-Redis](https://github.com/alphazero/Go-Redis) 14 | - [http://code.google.com/p/tideland-rdc/](http://code.google.com/p/tideland-rdc/) 15 | - [https://github.com/simonz05/godis](https://github.com/simonz05/godis) 16 | - [https://github.com/hoisie/redis.go](https://github.com/hoisie/redis.go) 17 | 18 | Le hice un fork al ultimo y le corregí algunos bugs, lo uso en mi servicio para acortar URL(2 millones de PV cada día). 19 | 20 | - [https://github.com/astaxie/goredis](https://github.com/astaxie/goredis) 21 | 22 | Vamos a ver cómo utilizar el driver al que le realicé el fork para operar la base de datos: 23 | 24 | ```go 25 | package main 26 | 27 | import ( 28 | "github.com/astaxie/goredis" 29 | "fmt" 30 | ) 31 | 32 | func main() { 33 | var client goredis.Client 34 | 35 | // Set the default port in Redis 36 | client.Addr = "127.0.0.1:6379" 37 | 38 | // string manipulation 39 | client.Set("a", []byte("hello")) 40 | val, _ := client.Get("a") 41 | fmt.Println(string(val)) 42 | client.Del("a") 43 | 44 | // list operation 45 | vals := []string{"a", "b", "c", "d", "e"} 46 | for _, v := range vals { 47 | client.Rpush("l", []byte(v)) 48 | } 49 | dbvals,_ := client.Lrange("l", 0, 4) 50 | for i, v := range dbvals { 51 | println(i,":",string(v)) 52 | } 53 | client.Del("l") 54 | } 55 | ``` 56 | 57 | Podemos ver que es muy fácil de operar redis en Go, y tiene un alto rendimiento. Su cliente de comandos es casi lo mismos que los mismo comandos que incorpora redis. 58 | 59 | ## mongoDB 60 | 61 | mongoDB (de "descomunal") es un sistema de base de datos orientada a documentos, de código abierto desarrollada y apoyada por 10gen. Es parte de la familia de los sistemas de base de datos NoSQL. En lugar de almacenar datos en tablas como se hace en una base de datos relacional "clásica", MongoDB guarda los datos estructurados como documentos JSON-like con esquemas dinámicos (MongoDB llama al formato BSON), por lo que la integración de datos en ciertos tipos de aplicaciones es más fácil y más rápido. 62 | 63 | ![](images/5.6.mongodb.png?raw=true) 64 | 65 | Figura 5.1 Comparación de MongoDB con Mysql 66 | 67 | El mejor driver para mongoDB se llama `mgo`, y es posible que este en la librería estándar en el futuro. 68 | 69 | Acá un ejemplo: 70 | 71 | ```go 72 | package main 73 | 74 | import ( 75 | "fmt" 76 | "labix.org/v2/mgo" 77 | "labix.org/v2/mgo/bson" 78 | ) 79 | 80 | type Person struct { 81 | Name string 82 | Phone string 83 | } 84 | 85 | func main() { 86 | session, err := mgo.Dial("server1.example.com,server2.example.com") 87 | if err != nil { 88 | panic(err) 89 | } 90 | defer session.Close() 91 | 92 | session.SetMode(mgo.Monotonic, true) 93 | 94 | c := session.DB("test").C("people") 95 | err = c.Insert(&Person{"Ale", "+55 53 8116 9639"}, 96 | &Person{"Cla", "+55 53 8402 8510"}) 97 | if err != nil { 98 | panic(err) 99 | } 100 | 101 | result := Person{} 102 | err = c.Find(bson.M{"name": "Ale"}).One(&result) 103 | if err != nil { 104 | panic(err) 105 | } 106 | 107 | fmt.Println("Phone:", result.Phone) 108 | } 109 | ``` 110 | 111 | Podemos ver que no hay grandes diferencias para operar la base de datos entre mgo y beedb, ambos están basados ​​en struct, esto es lo que se estila en Go. 112 | 113 | ## Enlaces 114 | 115 | - [Indice](preface.md) 116 | - Sección anterior: [Desarrollo de un ORM basado en beedb](05.5.md) 117 | - Siguiente sección: [Resumen](05.7.md) -------------------------------------------------------------------------------- /eBook/03.3.md: -------------------------------------------------------------------------------- 1 | # 3.3 Como trabaja Go con la web 2 | 3 | Hemos aprendido a utilizar el paquete `net/http` para construir un sencillo servidor web en el apartado anterior, pero todos los principios de trabajo son las mismas que hemos hablado en la primera sección de este capítulo . 4 | 5 | ## Algunos conceptos de los principios de trabajo web 6 | 7 | Request: solicitar datos de los usuarios, incluyendo la POST , GET, la Cookie y la URL. 8 | 9 | Response: datos de respuesta desde el servidor a los clientes. 10 | 11 | Conn: conexiones entre clientes y servidores. 12 | 13 | Handler: lógica para la gestión de solicitudes y respuestas de productos. 14 | 15 | ## Mecanismo de funcionamiento del paquete http 16 | 17 | La siguiente imagen muestra el flujo de trabajo del servidor web de Go. 18 | 19 | ![](images/3.3.http.png?raw=true) 20 | 21 | Figura flujo de trabajo 3.9 http 22 | 23 | 1. Crear socket y escucha en un puerto, esperando a los clientes . 24 | 2. Acepta peticiones de los clientes . 25 | 3. Tramitar las solicitudes, leer el encabezado HTTP, si se utiliza el método POST, también es necesario para leer los datos en el cuerpo del mensaje y signar a los controladores. Por último , devuelve datos de respuesta a los clientes. 26 | 27 | Una vez que conocemos las respuestas a lastres preguntas siguientes , es fácil saber cómo funciona la web en Go. 28 | 29 | - ¿Cómo escuchar un puerto? 30 | - ¿Cómo aceptar peticiones de cliente ? 31 | - ¿Cómo asignar controladores ? 32 | 33 | En la sección anterior vimos que Go utiliza ListenAndServe para manejar estos problemas : inicializar un objeto de servidor , llame net.Listen ( " tcp" , addr ) para configurar un puerto TCP de escucha y escuchar a la dirección y el puerto específico. 34 | 35 | Vamos a echar un vistazo a el código fuente del paquete `http`. 36 | 37 | //Build version go1.1.2. 38 | func (srv *Server) Serve(l net.Listener) error { 39 | defer l.Close() 40 | var tempDelay time.Duration // how long to sleep on accept failure 41 | for { 42 | rw, e := l.Accept() 43 | if e != nil { 44 | if ne, ok := e.(net.Error); ok && ne.Temporary() { 45 | if tempDelay == 0 { 46 | tempDelay = 5 * time.Millisecond 47 | } else { 48 | tempDelay *= 2 49 | } 50 | if max := 1 * time.Second; tempDelay > max { 51 | tempDelay = max 52 | } 53 | log.Printf("http: Accept error: %v; retrying in %v", e, tempDelay) 54 | time.Sleep(tempDelay) 55 | continue 56 | } 57 | return e 58 | } 59 | tempDelay = 0 60 | c, err := srv.newConn(rw) 61 | if err != nil { 62 | continue 63 | } 64 | go c.serve() 65 | } 66 | } 67 | 68 | ¿Cómo aceptar peticiones de cliente después de escuchar el puerto? En el código fuente , podemos ver que se llama `srv.Serve(net.Listener)` para manejar peticiones de clientes . En el cuerpo de la función hay un `for{}`, se acepta la solicitud, se crea una nueva conexión y, a continuación, se inicia un nuevo goroutine , y pasa los datos de solicitud a esta goroutine: `go c.serve()`. Así es como Go es compatible con alta concurrencia , y cada goroutine es independiente. 69 | 70 | Ahora, la forma de utilizar las funciones específicas para controlar las solicitudes? `conn` analiza la solicitud `c.ReadRequest()` al principio, y consegui el controlador correspondiente `handler : = c.server.Handler` que es el segundo argumento que pasábamos cuando llamamos `ListenAndServe`. Porque pasamos `nil`, por lo que Go usa su manejador controlador `handler = DefaultServeMux`. Entonces, ¿qué está haciendo `DefaultServeMux` aquí ? Bueno, esta es la variable de enrutador en este momento , se llama a las funciones de controlador de URL específicas . ¿Hemos fijar esto? Sí , lo hicimos. Recuerde que en la primera línea se utilizó `http.HandleFunc("/", sayhelloName)`. Es asi como se utiliza esta función para registrar el estado del router para la ruta "/". Cuando la dirección URL es `/` , el enrutador llama a la función `sayhelloName` . DefaultServeMux llama ServerHTTP para obtener la función de controlador de ruta diferente , y llama `sayhelloName` en este caso. Por último , el servidor escribe los datos y la respuesta a los clientes. 71 | Flujo de trabajo detallado: 72 | 73 | ![](images/3.3.illustrator.png?raw=true) 74 | 75 | Figura 3.10 Flujo de trabajo de manejar una petición HTTP 76 | 77 | Creo que usted debe saber cómo Go se ejecuta servidores web ahora. 78 | 79 | ## Enlaces 80 | 81 | - [Indice](preface.md) 82 | - Sección anterior: [Armando un servidor web sencillo](03.2.md) 83 | - Siguiente sección: [Obteniendo el paquete http](03.4.md) 84 | -------------------------------------------------------------------------------- /eBook/05.2.md: -------------------------------------------------------------------------------- 1 | # 5.2 MySQL 2 | 3 | Los framework llamados LAMP se hicieron muy popular en internet en los últimos años, y la M es de MySQL. MySQL es conocida por ser open source, sencilla de usar, por eso se convirtio en la base de datos en el back-end de muchos sitios web. 4 | 5 | ## Drivers MySQL 6 | 7 | Hay un par de drivers que soportan MySQL en Go, algunos de ellos implementados con la interfaz `database/sql`, y algunos de ellos usan su propia interfaz como estandar. 8 | 9 | - [https://github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) soporta `database/sql`, puro código Go. 10 | - [https://github.com/ziutek/mymysql](https://github.com/ziutek/mymysql) soporta `database/sql` y el usuario define la interfaz, puro código Go. 11 | - [https://github.com/Philio/GoMySQL](https://github.com/Philio/GoMySQL) solo es compatible con la interfaz definida por el usuario, puro código Go. 12 | 13 | Voy a usar el primer driver en los futuros ejemplos (Utilizo tambien el mismo en mis proyectos), y recomiendo su uso por las siguientes razones: 14 | 15 | - Es un nuevo driver y soporta más características. 16 | - Soporte completo para la interfaz estandar `databse/sql`. 17 | - Soporta keepalive, largas conexiones con thread-safe. 18 | 19 | ## Ejemplos 20 | 21 | En las siguientes secciones, voy a usar la misma estuctura de tabla para las diferentes base de datos, el SQL para crearla es el siguiente: 22 | 23 | ```sql 24 | CREATE TABLE `userinfo` ( 25 | `uid` INT(10) NOT NULL AUTO_INCREMENT, 26 | `username` VARCHAR(64) NULL DEFAULT NULL, 27 | `departname` VARCHAR(64) NULL DEFAULT NULL, 28 | `created` DATE NULL DEFAULT NULL, 29 | PRIMARY KEY (`uid`) 30 | ); 31 | ``` 32 | 33 | El siguiente ejemplo nos muestra como manejar la base de datos basado en la interfaz estandar `database/sql`. 34 | 35 | ```go 36 | package main 37 | 38 | import ( 39 | _ "github.com/go-sql-driver/mysql" 40 | "database/sql" 41 | "fmt" 42 | ) 43 | 44 | func main() { 45 | db, err := sql.Open("mysql", "astaxie:astaxie@/test?charset=utf8") 46 | checkErr(err) 47 | 48 | // insert 49 | stmt, err := db.Prepare("INSERT userinfo SET username=?,departname=?,created=?") 50 | checkErr(err) 51 | 52 | res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09") 53 | checkErr(err) 54 | 55 | id, err := res.LastInsertId() 56 | checkErr(err) 57 | 58 | fmt.Println(id) 59 | // update 60 | stmt, err = db.Prepare("update userinfo set username=? where uid=?") 61 | checkErr(err) 62 | 63 | res, err = stmt.Exec("astaxieupdate", id) 64 | checkErr(err) 65 | 66 | affect, err := res.RowsAffected() 67 | checkErr(err) 68 | 69 | fmt.Println(affect) 70 | 71 | // query 72 | rows, err := db.Query("SELECT * FROM userinfo") 73 | checkErr(err) 74 | 75 | for rows.Next() { 76 | var uid int 77 | var username string 78 | var department string 79 | var created string 80 | err = rows.Scan(&uid, &username, &department, &created) 81 | checkErr(err) 82 | fmt.Println(uid) 83 | fmt.Println(username) 84 | fmt.Println(department) 85 | fmt.Println(created) 86 | } 87 | 88 | // delete 89 | stmt, err = db.Prepare("delete from userinfo where uid=?") 90 | checkErr(err) 91 | 92 | res, err = stmt.Exec(id) 93 | checkErr(err) 94 | 95 | affect, err = res.RowsAffected() 96 | checkErr(err) 97 | 98 | fmt.Println(affect) 99 | 100 | db.Close() 101 | 102 | } 103 | 104 | func checkErr(err error) { 105 | if err != nil { 106 | panic(err) 107 | } 108 | } 109 | ``` 110 | 111 | Voy a explicar algunas funciones importantes: 112 | 113 | - `sql.Open()` abre el registro de la base de datos a travez del driver, aquí Go-MySQL-Driver registra el driver de mysql. El segundo argumento es el DSN(Data Source Name) que define información de la conexión a la base de datos, este soporta los siguientes formatos: 114 | 115 | user@unix(/path/to/socket)/dbname?charset=utf8 116 | user:password@tcp(localhost:5555)/dbname?charset=utf8 117 | user:password@/dbname 118 | user:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname 119 | 120 | - `db.Prepare()` nos devuelve la operación SQL que se va a ejecutar, también nos retorna el estado despues de la ejecución del SQL. 121 | - `db.Query()` ejecuta el SQL y nos devuelve Rows de resultado. 122 | - `stmt.Exec()` ejecuta el SQL que es preparado en Stmt. 123 | 124 | Tenga en cuenta que usamos el formato `=?` para pasarle los argumentos, esto es para prevenir inyecciones SQL. 125 | 126 | ## Enlaces 127 | 128 | - [Indice](preface.md) 129 | - Sección anterior: [database/sql interfaz](05.1.md) 130 | - Siguiente sección: [SQLite](05.3.md) -------------------------------------------------------------------------------- /eBook/06.3.md: -------------------------------------------------------------------------------- 1 | # 6.3 almacenamiento Sesión 2 | 3 | Introdujimos sobre los principios de como trabajar con en manejo de sesiones en seccón anterior, hemos definido una interfaz para el almacenamiento de sesiones. En esta sección, voy a mostrar un ejemplo de motor de almacenamiento de sesiones basado en memoria que implementa la interfaz. Usted puedrá cambiar esto a otras formas de almacenamiento de sesiones. 4 | 5 | ```go 6 | package memory 7 | 8 | import ( 9 | "container/list" 10 | "github.com/astaxie/session" 11 | "sync" 12 | "time" 13 | ) 14 | 15 | var pder = &Provider{list: list.New()} 16 | 17 | type SessionStore struct { 18 | sid string // unique session id 19 | timeAccessed time.Time // last access time 20 | value map[interface{}]interface{} // session value stored inside 21 | } 22 | 23 | func (st *SessionStore) Set(key, value interface{}) error { 24 | st.value[key] = value 25 | pder.SessionUpdate(st.sid) 26 | return nil 27 | } 28 | 29 | func (st *SessionStore) Get(key interface{}) interface{} { 30 | pder.SessionUpdate(st.sid) 31 | if v, ok := st.value[key]; ok { 32 | return v 33 | } else { 34 | return nil 35 | } 36 | return nil 37 | } 38 | 39 | func (st *SessionStore) Delete(key interface{}) error { 40 | delete(st.value, key) 41 | pder.SessionUpdate(st.sid) 42 | return nil 43 | } 44 | 45 | func (st *SessionStore) SessionID() string { 46 | return st.sid 47 | } 48 | 49 | type Provider struct { 50 | lock sync.Mutex // lock 51 | sessions map[string]*list.Element // save in memory 52 | list *list.List // gc 53 | } 54 | 55 | func (pder *Provider) SessionInit(sid string) (session.Session, error) { 56 | pder.lock.Lock() 57 | defer pder.lock.Unlock() 58 | v := make(map[interface{}]interface{}, 0) 59 | newsess := &SessionStore{sid: sid, timeAccessed: time.Now(), value: v} 60 | element := pder.list.PushBack(newsess) 61 | pder.sessions[sid] = element 62 | return newsess, nil 63 | } 64 | 65 | func (pder *Provider) SessionRead(sid string) (session.Session, error) { 66 | if element, ok := pder.sessions[sid]; ok { 67 | return element.Value.(*SessionStore), nil 68 | } else { 69 | sess, err := pder.SessionInit(sid) 70 | return sess, err 71 | } 72 | return nil, nil 73 | } 74 | 75 | func (pder *Provider) SessionDestroy(sid string) error { 76 | if element, ok := pder.sessions[sid]; ok { 77 | delete(pder.sessions, sid) 78 | pder.list.Remove(element) 79 | return nil 80 | } 81 | return nil 82 | } 83 | 84 | func (pder *Provider) SessionGC(maxlifetime int64) { 85 | pder.lock.Lock() 86 | defer pder.lock.Unlock() 87 | 88 | for { 89 | element := pder.list.Back() 90 | if element == nil { 91 | break 92 | } 93 | if (element.Value.(*SessionStore).timeAccessed.Unix() + maxlifetime) < time.Now().Unix() { 94 | pder.list.Remove(element) 95 | delete(pder.sessions, element.Value.(*SessionStore).sid) 96 | } else { 97 | break 98 | } 99 | } 100 | } 101 | 102 | func (pder *Provider) SessionUpdate(sid string) error { 103 | pder.lock.Lock() 104 | defer pder.lock.Unlock() 105 | if element, ok := pder.sessions[sid]; ok { 106 | element.Value.(*SessionStore).timeAccessed = time.Now() 107 | pder.list.MoveToFront(element) 108 | return nil 109 | } 110 | return nil 111 | } 112 | 113 | func init() { 114 | pder.sessions = make(map[string]*list.Element, 0) 115 | session.Register("memory", pder) 116 | } 117 | ``` 118 | 119 | En el ejemplo anterior se puso en marcha un mecanismo de almacenamiento de sesiones basado en memoria, a continuación, vamos a utilizar la función `init()` para registrar este motor de almacenamiento al administrador de sesiones. Entonces, ¿cómo registramos este motor? 120 | 121 | ```go 122 | import ( 123 | "github.com/astaxie/session" 124 | _ "github.com/astaxie/session/providers/memory" 125 | ) 126 | ``` 127 | 128 | Usamos el mecanisco import para registrar este motor en la función init() automaticamente al manejador de sesiones, entonces vamos a usar el siguiente código para inicializar el manejador de sesiones: 129 | 130 | ```go 131 | var globalSessions *session.Manager 132 | 133 | // initialize in init() function 134 | func init() { 135 | globalSessions, _ = session.NewManager("memory", "gosessionid", 3600) 136 | go globalSessions.GC() 137 | } 138 | ``` 139 | 140 | ## Enlaces 141 | 142 | - [Indice](preface.md) 143 | - Sección anterior: [Como usar sesiones en Go](06.2.md) 144 | - Siguiente sección: [Prevenir hijack de la sesión](06.4.md) -------------------------------------------------------------------------------- /eBook/07.6.md: -------------------------------------------------------------------------------- 1 | # 7.6 cadenas de texto 2 | 3 | Casi todo lo que vemos está representado por string, por lo que es una parte muy importante del desarrollo web, incluyendo las entradas de usuario, acceso a bases de datos; También tenemos que dividir, unir y convertir cadenas en muchos casos. En esta sección, vamos a introducir los paquetes `strings` and `strconv` en Go biblioteca estándar. 4 | 5 | ## strings 6 | 7 | Las siguientes funciones son del package `strings`, más detalles, ver la documentación oficial: 8 | 9 | - func Contains(s, substr string) bool 10 | 11 | Compruebe si la cadena `s` contiene string `substr`, devuelve el valor booleano. 12 | 13 | fmt.Println(strings.Contains("seafood", "foo")) 14 | fmt.Println(strings.Contains("seafood", "bar")) 15 | fmt.Println(strings.Contains("seafood", "")) 16 | fmt.Println(strings.Contains("", "")) 17 | //Output: 18 | //true 19 | //false 20 | //true 21 | //true 22 | 23 | - func Join(a []string, sep string) string 24 | 25 | Combina strings de un slice con el separador `sep`. 26 | 27 | s := []string{"foo", "bar", "baz"} 28 | fmt.Println(strings.Join(s, ", ")) 29 | //Output:foo, bar, baz 30 | 31 | - func Index(s, sep string) int 32 | 33 | Encuentra el index `sep` en el string `s`, retorna -1 si no lo encuentra. 34 | 35 | fmt.Println(strings.Index("chicken", "ken")) 36 | fmt.Println(strings.Index("chicken", "dmr")) 37 | //Output:4 38 | //-1 39 | 40 | - func Repeat(s string, count int) string 41 | 42 | Repite el string `s` con `count` veces. 43 | 44 | fmt.Println("ba" + strings.Repeat("na", 2)) 45 | //Output:banana 46 | 47 | - func Replace(s, old, new string, n int) string 48 | 49 | Reemplaza el string `old` con el string `new` en el string `s`, `n` ignifica tiempos de replicación, si n es menor que 0 significa reemplazar todos. 50 | 51 | fmt.Println(strings.Replace("oink oink oink", "k", "ky", 2)) 52 | fmt.Println(strings.Replace("oink oink oink", "oink", "moo", -1)) 53 | //Output:oinky oinky oink 54 | //moo moo moo 55 | 56 | - func Split(s, sep string) []string 57 | 58 | Separar el string `s` con el separador `sep` en el slice. 59 | 60 | fmt.Printf("%q\n", strings.Split("a,b,c", ",")) 61 | fmt.Printf("%q\n", strings.Split("a man a plan a canal panama", "a ")) 62 | fmt.Printf("%q\n", strings.Split(" xyz ", "")) 63 | fmt.Printf("%q\n", strings.Split("", "Bernardo O'Higgins")) 64 | //Output:["a" "b" "c"] 65 | //["" "man " "plan " "canal panama"] 66 | //[" " "x" "y" "z" " "] 67 | //[""] 68 | 69 | - func Trim(s string, cutset string) string 70 | 71 | Remueve `cutset` del string `s` si esta a la derecha o izquierda. 72 | 73 | fmt.Printf("[%q]", strings.Trim(" !!! Achtung !!! ", "! ")) 74 | Output:["Achtung"] 75 | 76 | - func Fields(s string) []string 77 | 78 | Remueve los espaciositems and split string with space in to a slice. 79 | 80 | fmt.Printf("Fields are: %q", strings.Fields(" foo bar baz ")) 81 | //Output:Fields are: ["foo" "bar" "baz"] 82 | 83 | 84 | ## strconv 85 | 86 | Las siguientes funciones son del package `strconv` , más detalles, consulte la documentación oficial: 87 | 88 | - Append series convert data to string and append to current byte slice. 89 | 90 | package main 91 | 92 | import ( 93 | "fmt" 94 | "strconv" 95 | ) 96 | 97 | func main() { 98 | str := make([]byte, 0, 100) 99 | str = strconv.AppendInt(str, 4567, 10) 100 | str = strconv.AppendBool(str, false) 101 | str = strconv.AppendQuote(str, "abcdefg") 102 | str = strconv.AppendQuoteRune(str, '单') 103 | fmt.Println(string(str)) 104 | } 105 | 106 | - Format series convertir otros datos de tipo de cadena. 107 | 108 | package main 109 | 110 | import ( 111 | "fmt" 112 | "strconv" 113 | ) 114 | 115 | func main() { 116 | a := strconv.FormatBool(false) 117 | b := strconv.FormatFloat(123.23, 'g', 12, 64) 118 | c := strconv.FormatInt(1234, 10) 119 | d := strconv.FormatUint(12345, 10) 120 | e := strconv.Itoa(1023) 121 | fmt.Println(a, b, c, d, e) 122 | } 123 | 124 | - Parse series convertir string a otros tipos. 125 | 126 | package main 127 | 128 | import ( 129 | "fmt" 130 | "strconv" 131 | ) 132 | 133 | func main() { 134 | a, err := strconv.ParseBool("false") 135 | if err != nil { 136 | fmt.Println(err) 137 | } 138 | b, err := strconv.ParseFloat("123.23", 64) 139 | if err != nil { 140 | fmt.Println(err) 141 | } 142 | c, err := strconv.ParseInt("1234", 10, 64) 143 | if err != nil { 144 | fmt.Println(err) 145 | } 146 | d, err := strconv.ParseUint("12345", 10, 64) 147 | if err != nil { 148 | fmt.Println(err) 149 | } 150 | e, err := strconv.Itoa("1023") 151 | if err != nil { 152 | fmt.Println(err) 153 | } 154 | fmt.Println(a, b, c, d, e) 155 | } 156 | 157 | ## Links 158 | 159 | - [Directory](preface.md) 160 | - Previous section: [Files](07.5.md) 161 | - Next section: [Summary](07.7.md) 162 | -------------------------------------------------------------------------------- /code/src/apps/ch.5.5/main.go: -------------------------------------------------------------------------------- 1 | // Example code for Chapter 5.5 2 | // Purpose is to show to use BeeDB ORM for basic CRUD operations for sqlite3 3 | package main 4 | 5 | import ( 6 | "database/sql" 7 | "fmt" 8 | "github.com/astaxie/beedb" 9 | _ "github.com/mattn/go-sqlite3" 10 | "time" 11 | ) 12 | 13 | var orm beedb.Model 14 | 15 | type Userinfo struct { 16 | Uid int `beedb:"PK"` 17 | Username string 18 | Department string 19 | Created string 20 | } 21 | 22 | const DB_PATH = "./foo.db" 23 | 24 | func checkError(err error) { 25 | if err != nil { 26 | panic(err) 27 | } 28 | } 29 | func getTimeStamp() string { 30 | return time.Now().Format("2006-01-02 15:04:05") 31 | } 32 | func insertUsingStruct() int64 { 33 | fmt.Println("insertUsingStruct()") 34 | var obj Userinfo 35 | obj.Username = "Test Add User" 36 | obj.Department = "Test Add Department" 37 | obj.Created = getTimeStamp() 38 | checkError(orm.Save(&obj)) 39 | fmt.Printf("%+v\n", obj) 40 | return int64(obj.Uid) 41 | } 42 | func insertUsingMap() int64 { 43 | fmt.Println("insertUsingMap()") 44 | add := make(map[string]interface{}) 45 | add["username"] = "astaxie" 46 | add["department"] = "cloud develop" 47 | add["created"] = getTimeStamp() 48 | id, err := orm.SetTable("userinfo").Insert(add) 49 | checkError(err) 50 | fmt.Println("Last row inserted id =", id) 51 | return id 52 | } 53 | 54 | func getOneUserInfo(id int64) Userinfo { 55 | fmt.Println("getOneUserInfo()") 56 | var obj Userinfo 57 | checkError(orm.Where("uid=?", id).Find(&obj)) 58 | return obj 59 | } 60 | 61 | func getAllUserInfo(id int64) []Userinfo { 62 | fmt.Println("getAllUserInfo()") 63 | var alluser []Userinfo 64 | checkError(orm.Limit(10).Where("uid>?", id).FindAll(&alluser)) 65 | return alluser 66 | } 67 | 68 | func updateUserinfo(id int64) { 69 | fmt.Println("updateUserinfo()") 70 | var obj Userinfo 71 | obj.Uid = int(id) 72 | obj.Username = "Update Username" 73 | obj.Department = "Update Department" 74 | obj.Created = getTimeStamp() 75 | checkError(orm.Save(&obj)) 76 | fmt.Printf("%+v\n", obj) 77 | } 78 | 79 | func updateUsingMap(id int64) { 80 | fmt.Println("updateUsingMap()") 81 | t := make(map[string]interface{}) 82 | t["username"] = "updateastaxie" 83 | //update one 84 | // id, err := orm.SetTable("userinfo").SetPK("uid").Where(2).Update(t) 85 | //update batch 86 | lastId, err := orm.SetTable("userinfo").Where("uid>?", id).Update(t) 87 | checkError(err) 88 | fmt.Println("Last row updated id =", lastId) 89 | } 90 | 91 | func getMapsFromSelect(id int64) []map[string][]byte { 92 | fmt.Println("getMapsFromSelect()") 93 | //Original SQL Backinfo resultsSlice []map[string][]byte 94 | //default PrimaryKey id 95 | c, err := orm.SetTable("userinfo").SetPK("uid").Where(id).Select("uid,username").FindMap() 96 | checkError(err) 97 | fmt.Printf("%+v\n", c) 98 | return c 99 | } 100 | 101 | func groupby() { 102 | fmt.Println("groupby()") 103 | //Original SQL Group By 104 | b, err := orm.SetTable("userinfo").GroupBy("username").Having("username='updateastaxie'").FindMap() 105 | checkError(err) 106 | fmt.Printf("%+v\n", b) 107 | } 108 | 109 | func joinTables(id int64) { 110 | fmt.Println("joinTables()") 111 | //Original SQL Join Table 112 | a, err := orm.SetTable("userinfo").Join("LEFT", "userdetail", "userinfo.uid=userdetail.uid").Where("userinfo.uid=?", id).Select("userinfo.uid,userinfo.username,userdetail.profile").FindMap() 113 | checkError(err) 114 | fmt.Printf("%+v\n", a) 115 | } 116 | 117 | func deleteWithUserinfo(id int64) { 118 | fmt.Println("deleteWithUserinfo()") 119 | obj := getOneUserInfo(id) 120 | id, err := orm.Delete(&obj) 121 | checkError(err) 122 | fmt.Println("Last row deleted id =", id) 123 | } 124 | 125 | func deleteRows() { 126 | fmt.Println("deleteRows()") 127 | //original SQL delete 128 | id, err := orm.SetTable("userinfo").Where("uid>?", 2).DeleteRow() 129 | checkError(err) 130 | fmt.Println("Last row updated id =", id) 131 | } 132 | 133 | func deleteAllUserinfo(id int64) { 134 | fmt.Println("deleteAllUserinfo()") 135 | //delete all data 136 | alluser := getAllUserInfo(id) 137 | id, err := orm.DeleteAll(&alluser) 138 | checkError(err) 139 | fmt.Println("Last row updated id =", id) 140 | } 141 | func main() { 142 | db, err := sql.Open("sqlite3", DB_PATH) 143 | checkError(err) 144 | orm = beedb.New(db) 145 | var lastIdInserted int64 146 | 147 | fmt.Println("Inserting") 148 | lastIdInserted = insertUsingStruct() 149 | insertUsingMap() 150 | 151 | a := getOneUserInfo(lastIdInserted) 152 | fmt.Println(a) 153 | 154 | b := getAllUserInfo(lastIdInserted) 155 | fmt.Println(b) 156 | 157 | fmt.Println("Updating") 158 | updateUserinfo(lastIdInserted) 159 | updateUsingMap(lastIdInserted) 160 | 161 | fmt.Println("Querying") 162 | getMapsFromSelect(lastIdInserted) 163 | groupby() 164 | joinTables(lastIdInserted) 165 | 166 | fmt.Println("Deleting") 167 | deleteWithUserinfo(lastIdInserted) 168 | deleteRows() 169 | deleteAllUserinfo(lastIdInserted) 170 | } 171 | --------------------------------------------------------------------------------