├── chapter10
├── 2_godeps
│ ├── Godeps
│ │ ├── _workspace
│ │ │ ├── .gitignore
│ │ │ └── src
│ │ │ │ ├── github.com
│ │ │ │ ├── julienschmidt
│ │ │ │ │ └── httprouter
│ │ │ │ │ │ └── .travis.yml
│ │ │ │ └── go-sql-driver
│ │ │ │ │ └── mysql
│ │ │ │ │ ├── .gitignore
│ │ │ │ │ ├── .travis.yml
│ │ │ │ │ ├── appengine.go
│ │ │ │ │ ├── result.go
│ │ │ │ │ └── transaction.go
│ │ │ │ └── golang.org
│ │ │ │ └── x
│ │ │ │ └── image
│ │ │ │ └── tiff
│ │ │ │ └── buffer_test.go
│ │ └── Readme
│ ├── templates
│ │ ├── index
│ │ │ └── home.html
│ │ ├── sessions
│ │ │ ├── destroy.html
│ │ │ └── new.html
│ │ ├── images
│ │ │ ├── index.html
│ │ │ └── show.html
│ │ └── users
│ │ │ ├── show.html
│ │ │ └── new.html
│ ├── auth.go
│ ├── mysql.go
│ ├── handle_index.go
│ ├── id.go
│ └── image_test.go
├── 0_base
│ ├── templates
│ │ ├── index
│ │ │ └── home.html
│ │ ├── sessions
│ │ │ ├── destroy.html
│ │ │ └── new.html
│ │ ├── images
│ │ │ ├── index.html
│ │ │ ├── show.html
│ │ │ └── new.html
│ │ └── users
│ │ │ ├── show.html
│ │ │ └── new.html
│ ├── auth.go
│ ├── mysql.go
│ ├── handle_index.go
│ ├── id.go
│ └── image_test.go
├── 1_pkg_web
│ ├── templates
│ │ ├── index
│ │ │ └── home.html
│ │ ├── sessions
│ │ │ ├── destroy.html
│ │ │ └── new.html
│ │ ├── images
│ │ │ ├── index.html
│ │ │ └── show.html
│ │ └── users
│ │ │ ├── show.html
│ │ │ └── new.html
│ ├── auth.go
│ ├── mysql.go
│ ├── handle_index.go
│ ├── id.go
│ └── image_test.go
└── examples
│ ├── 1_pkg_foo
│ ├── main.go
│ └── foo
│ │ └── foo.go
│ └── 2_exporting_values
│ ├── main.go
│ └── foo
│ └── foo.go
├── chapter4
├── 1_file_server
│ ├── assets
│ │ └── test.txt
│ └── main.go
├── 4_httprouter
│ ├── templates
│ │ ├── users
│ │ │ └── new.html
│ │ ├── layout.html
│ │ └── index
│ │ │ └── home.html
│ ├── handle_index.go
│ ├── handle_user.go
│ ├── auth.go
│ └── handle_image.go
├── 3_layouts
│ ├── templates
│ │ ├── layout.html
│ │ └── index
│ │ │ └── home.html
│ └── main.go
└── 2_first_template
│ ├── main.go
│ ├── templates
│ └── index
│ │ └── home.html
│ └── template.go
├── chapter5
├── 0_base
│ ├── _base
│ ├── templates
│ │ ├── index
│ │ │ └── home.html
│ │ └── layout.html
│ ├── handle_index.go
│ ├── auth.go
│ └── main.go
├── 1_router
│ ├── templates
│ │ ├── index
│ │ │ └── home.html
│ │ └── layout.html
│ ├── handle_index.go
│ ├── auth.go
│ └── main.go
├── 2_registration
│ ├── templates
│ │ ├── index
│ │ │ └── home.html
│ │ ├── layout.html
│ │ └── users
│ │ │ └── new.html
│ ├── handle_index.go
│ ├── auth.go
│ ├── errors.go
│ ├── main.go
│ ├── handle_user.go
│ ├── id.go
│ └── user.go
└── 3_user_store
│ ├── templates
│ ├── index
│ │ └── home.html
│ ├── layout.html
│ └── users
│ │ └── new.html
│ ├── handle_index.go
│ ├── auth.go
│ ├── errors.go
│ ├── main.go
│ ├── id.go
│ └── handle_user.go
├── chapter6
├── 0_base
│ ├── templates
│ │ ├── index
│ │ │ └── home.html
│ │ ├── layout.html
│ │ └── users
│ │ │ └── new.html
│ ├── handle_index.go
│ ├── auth.go
│ ├── errors.go
│ ├── main.go
│ ├── id.go
│ └── handle_user.go
├── 1_new_session
│ ├── templates
│ │ ├── index
│ │ │ └── home.html
│ │ ├── layout.html
│ │ └── users
│ │ │ └── new.html
│ ├── data
│ │ └── users.json
│ ├── handle_index.go
│ ├── auth.go
│ ├── errors.go
│ ├── main.go
│ ├── session.go
│ └── id.go
├── 2_session_store
│ ├── templates
│ │ ├── index
│ │ │ └── home.html
│ │ ├── layout.html
│ │ └── users
│ │ │ └── new.html
│ ├── data
│ │ └── sessions.json
│ ├── handle_index.go
│ ├── auth.go
│ ├── errors.go
│ ├── main.go
│ ├── session.go
│ └── id.go
├── 3_require_login
│ ├── templates
│ │ ├── index
│ │ │ └── home.html
│ │ ├── layout.html
│ │ └── users
│ │ │ └── new.html
│ ├── data
│ │ └── sessions.json
│ ├── handle_index.go
│ ├── auth.go
│ ├── errors.go
│ ├── main.go
│ └── id.go
├── 4_template_data
│ ├── templates
│ │ ├── index
│ │ │ └── home.html
│ │ ├── users
│ │ │ └── new.html
│ │ └── layout.html
│ ├── handle_index.go
│ ├── auth.go
│ ├── data
│ │ └── sessions.json
│ ├── errors.go
│ ├── main.go
│ └── id.go
├── 6_edit_user
│ ├── templates
│ │ ├── index
│ │ │ └── home.html
│ │ ├── sessions
│ │ │ ├── destroy.html
│ │ │ └── new.html
│ │ ├── users
│ │ │ └── new.html
│ │ └── layout.html
│ ├── data
│ │ ├── users.json
│ │ └── sessions.json
│ ├── handle_index.go
│ ├── auth.go
│ ├── id.go
│ └── errors.go
└── 5_signing_out_and_in
│ ├── templates
│ ├── index
│ │ └── home.html
│ ├── sessions
│ │ ├── destroy.html
│ │ └── new.html
│ ├── users
│ │ └── new.html
│ └── layout.html
│ ├── data
│ ├── users.json
│ └── sessions.json
│ ├── handle_index.go
│ ├── auth.go
│ ├── id.go
│ └── errors.go
├── chapter7
├── 0_base
│ ├── templates
│ │ ├── index
│ │ │ └── home.html
│ │ ├── sessions
│ │ │ ├── destroy.html
│ │ │ └── new.html
│ │ ├── users
│ │ │ └── new.html
│ │ └── layout.html
│ ├── handle_index.go
│ ├── auth.go
│ ├── id.go
│ └── errors.go
├── 1_mysql
│ ├── templates
│ │ ├── index
│ │ │ └── home.html
│ │ ├── sessions
│ │ │ ├── destroy.html
│ │ │ └── new.html
│ │ ├── users
│ │ │ └── new.html
│ │ └── layout.html
│ ├── image_store.go
│ ├── image.go
│ ├── handle_index.go
│ ├── auth.go
│ ├── mysql.go
│ ├── id.go
│ └── errors.go
├── 2_db_image_store
│ ├── templates
│ │ ├── index
│ │ │ └── home.html
│ │ ├── sessions
│ │ │ ├── destroy.html
│ │ │ └── new.html
│ │ ├── users
│ │ │ └── new.html
│ │ └── layout.html
│ ├── image.go
│ ├── handle_index.go
│ ├── auth.go
│ ├── mysql.go
│ ├── id.go
│ └── errors.go
├── 3_uploading_images
│ ├── templates
│ │ ├── index
│ │ │ └── home.html
│ │ ├── sessions
│ │ │ ├── destroy.html
│ │ │ └── new.html
│ │ └── users
│ │ │ └── new.html
│ ├── handle_index.go
│ ├── auth.go
│ ├── mysql.go
│ └── id.go
└── 4_displaying_images
│ ├── templates
│ ├── index
│ │ └── home.html
│ ├── sessions
│ │ ├── destroy.html
│ │ └── new.html
│ ├── images
│ │ ├── index.html
│ │ └── show.html
│ └── users
│ │ ├── show.html
│ │ └── new.html
│ ├── auth.go
│ ├── mysql.go
│ ├── handle_index.go
│ └── id.go
├── ig
├── templates
│ ├── index
│ │ └── home.html
│ ├── errors
│ │ └── 500.html
│ ├── sessions
│ │ ├── destroy.html
│ │ └── new.html
│ ├── images
│ │ ├── index.html
│ │ ├── show.html
│ │ └── new.html
│ └── users
│ │ ├── show.html
│ │ └── new.html
├── data
│ ├── images
│ │ ├── img_0qlPyyrjrQ.png
│ │ └── img_IZ0nStUnWw.png
│ └── users.json
├── router.go
├── handle_frontpage.go
├── response.go
├── mysql.go
└── id.go
├── chapter8
├── 0_base
│ ├── templates
│ │ ├── index
│ │ │ └── home.html
│ │ ├── sessions
│ │ │ ├── destroy.html
│ │ │ └── new.html
│ │ ├── images
│ │ │ ├── index.html
│ │ │ ├── show.html
│ │ │ └── new.html
│ │ └── users
│ │ │ ├── show.html
│ │ │ └── new.html
│ ├── auth.go
│ ├── mysql.go
│ ├── handle_index.go
│ └── id.go
├── 1_image_resizing
│ ├── templates
│ │ ├── index
│ │ │ └── home.html
│ │ ├── sessions
│ │ │ ├── destroy.html
│ │ │ └── new.html
│ │ ├── images
│ │ │ ├── index.html
│ │ │ └── show.html
│ │ └── users
│ │ │ ├── show.html
│ │ │ └── new.html
│ ├── auth.go
│ ├── mysql.go
│ ├── handle_index.go
│ └── id.go
└── 2_display_resized
│ ├── templates
│ ├── index
│ │ └── home.html
│ ├── sessions
│ │ ├── destroy.html
│ │ └── new.html
│ ├── images
│ │ ├── index.html
│ │ └── show.html
│ └── users
│ │ ├── show.html
│ │ └── new.html
│ ├── auth.go
│ ├── mysql.go
│ ├── handle_index.go
│ └── id.go
├── chapter9
├── 0_base
│ ├── templates
│ │ ├── index
│ │ │ └── home.html
│ │ ├── sessions
│ │ │ ├── destroy.html
│ │ │ └── new.html
│ │ ├── images
│ │ │ ├── index.html
│ │ │ ├── show.html
│ │ │ └── new.html
│ │ └── users
│ │ │ ├── show.html
│ │ │ └── new.html
│ ├── auth.go
│ ├── mysql.go
│ ├── handle_index.go
│ └── id.go
├── 2_mock_interface
│ ├── templates
│ │ ├── index
│ │ │ └── home.html
│ │ ├── sessions
│ │ │ ├── destroy.html
│ │ │ └── new.html
│ │ ├── images
│ │ │ ├── index.html
│ │ │ └── show.html
│ │ └── users
│ │ │ ├── show.html
│ │ │ └── new.html
│ ├── auth.go
│ ├── mysql.go
│ ├── handle_index.go
│ └── id.go
├── 3_http_testing
│ ├── templates
│ │ ├── index
│ │ │ └── home.html
│ │ ├── sessions
│ │ │ ├── destroy.html
│ │ │ └── new.html
│ │ ├── images
│ │ │ ├── index.html
│ │ │ └── show.html
│ │ └── users
│ │ │ ├── show.html
│ │ │ └── new.html
│ ├── auth.go
│ ├── mysql.go
│ ├── handle_index.go
│ ├── id.go
│ └── image_test.go
├── 4_benchmarking
│ ├── templates
│ │ ├── index
│ │ │ └── home.html
│ │ ├── sessions
│ │ │ ├── destroy.html
│ │ │ └── new.html
│ │ ├── images
│ │ │ ├── index.html
│ │ │ └── show.html
│ │ └── users
│ │ │ ├── show.html
│ │ │ └── new.html
│ ├── auth.go
│ ├── mysql.go
│ ├── handle_index.go
│ ├── id.go
│ └── image_test.go
├── 1_simple_input_tests
│ ├── templates
│ │ ├── index
│ │ │ └── home.html
│ │ ├── sessions
│ │ │ ├── destroy.html
│ │ │ └── new.html
│ │ ├── images
│ │ │ ├── index.html
│ │ │ └── show.html
│ │ └── users
│ │ │ ├── show.html
│ │ │ └── new.html
│ ├── auth.go
│ ├── mysql.go
│ ├── handle_index.go
│ ├── user_test.go
│ └── id.go
└── examples
│ ├── 1_addition
│ └── addition_test.go
│ └── 2_wrapper_functions
│ └── main.go
├── chapter1
├── helloworld.go
└── starwars.go
├── chapter3
├── 7-unmarshaling-json
│ ├── config.json
│ └── main.go
├── 1-hello-world
│ └── hello.go
├── 2-extra-headers
│ └── main.go
├── 3-time-handler
│ └── main.go
├── 8-unknown-json-input
│ └── main.go
└── 5-html-templates
│ └── funcs
│ └── main.go
├── README.md
└── chapter2
└── markdown.go
/chapter10/2_godeps/Godeps/_workspace/.gitignore:
--------------------------------------------------------------------------------
1 | /pkg
2 | /bin
3 |
--------------------------------------------------------------------------------
/chapter4/1_file_server/assets/test.txt:
--------------------------------------------------------------------------------
1 | This is a static text file!
2 |
--------------------------------------------------------------------------------
/chapter5/0_base/_base:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spbooks/go1/HEAD/chapter5/0_base/_base
--------------------------------------------------------------------------------
/chapter5/0_base/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 |
Home
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter5/1_router/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | Home
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter6/0_base/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | Home
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter7/0_base/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | Home
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter7/1_mysql/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | Home
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/ig/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | {{template "images/index" .}}
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter4/4_httprouter/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 | New User
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter5/2_registration/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | Home
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter5/3_user_store/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | Home
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter6/1_new_session/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | Home
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter6/2_session_store/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | Home
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter6/3_require_login/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | Home
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter6/4_template_data/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | Home
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter6/6_edit_user/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | Home
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter6/5_signing_out_and_in/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | Home
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter7/2_db_image_store/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | Home
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter7/3_uploading_images/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | Home
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/ig/data/images/img_0qlPyyrjrQ.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spbooks/go1/HEAD/ig/data/images/img_0qlPyyrjrQ.png
--------------------------------------------------------------------------------
/ig/data/images/img_IZ0nStUnWw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spbooks/go1/HEAD/ig/data/images/img_IZ0nStUnWw.png
--------------------------------------------------------------------------------
/chapter10/0_base/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | {{template "images/index" .}}
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter8/0_base/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | {{template "images/index" .}}
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter9/0_base/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | {{template "images/index" .}}
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter1/helloworld.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | fmt.Println("Hello World")
7 | }
8 |
--------------------------------------------------------------------------------
/chapter10/1_pkg_web/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | {{template "images/index" .}}
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter10/2_godeps/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | {{template "images/index" .}}
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter10/examples/1_pkg_foo/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "./foo"
4 |
5 | func main() {
6 | foo.PrintFoo()
7 | }
8 |
--------------------------------------------------------------------------------
/chapter8/1_image_resizing/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | {{template "images/index" .}}
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter8/2_display_resized/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | {{template "images/index" .}}
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter9/2_mock_interface/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | {{template "images/index" .}}
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter9/3_http_testing/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | {{template "images/index" .}}
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter9/4_benchmarking/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | {{template "images/index" .}}
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter7/4_displaying_images/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | {{template "images/index" .}}
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/chapter9/1_simple_input_tests/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 | {{template "images/index" .}}
3 | {{end}}
4 |
--------------------------------------------------------------------------------
/ig/templates/errors/500.html:
--------------------------------------------------------------------------------
1 | {{define "errors/500"}}
2 | An Unexpected Error occurred
3 | {{.Error}}
4 | {{end}}
5 |
--------------------------------------------------------------------------------
/chapter10/examples/1_pkg_foo/foo/foo.go:
--------------------------------------------------------------------------------
1 | package foo
2 |
3 | import "fmt"
4 |
5 | func PrintFoo() {
6 | fmt.Println("foo")
7 | }
8 |
--------------------------------------------------------------------------------
/chapter10/2_godeps/Godeps/_workspace/src/github.com/julienschmidt/httprouter/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 | go:
3 | - 1.1
4 | - 1.2
5 | - 1.3
6 | - tip
7 |
--------------------------------------------------------------------------------
/chapter10/examples/2_exporting_values/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "./foo"
4 |
5 | func main() {
6 | myBar := foo.NewBar()
7 | myBar.status()
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/chapter10/2_godeps/Godeps/Readme:
--------------------------------------------------------------------------------
1 | This directory tree is generated automatically by godep.
2 |
3 | Please do not edit.
4 |
5 | See https://github.com/tools/godep for more information.
6 |
--------------------------------------------------------------------------------
/chapter10/2_godeps/Godeps/_workspace/src/github.com/go-sql-driver/mysql/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .DS_Store?
3 | ._*
4 | .Spotlight-V100
5 | .Trashes
6 | Icon?
7 | ehthumbs.db
8 | Thumbs.db
9 |
--------------------------------------------------------------------------------
/chapter4/3_layouts/templates/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{ yield }}
7 |
8 |
9 |
--------------------------------------------------------------------------------
/chapter4/4_httprouter/templates/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{ yield }}
7 |
8 |
9 |
--------------------------------------------------------------------------------
/chapter10/2_godeps/Godeps/_workspace/src/github.com/go-sql-driver/mysql/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 | go:
3 | - 1.1
4 | - tip
5 |
6 | before_script:
7 | - mysql -e 'create database gotest;'
8 |
--------------------------------------------------------------------------------
/chapter7/1_mysql/image_store.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | type ImageStore interface {
4 | Save(image *Image) error
5 | Find(id string) (*Image, error)
6 | FindAll(offset int) ([]Image, error)
7 | FindAllByUser(user *User, offset int) ([]Image, error)
8 | }
9 |
--------------------------------------------------------------------------------
/chapter6/2_session_store/data/sessions.json:
--------------------------------------------------------------------------------
1 | {
2 | "Sessions": {
3 | "sess_GBEX1Qx0NXmSgXL1nPDg": {
4 | "Id": "sess_GBEX1Qx0NXmSgXL1nPDg",
5 | "UserId": "usr_CydtIC9KUZG0Cbjx",
6 | "Expiry": "2014-10-16T21:52:36.144147885+13:00"
7 | }
8 | }
9 | }
--------------------------------------------------------------------------------
/chapter6/3_require_login/data/sessions.json:
--------------------------------------------------------------------------------
1 | {
2 | "Sessions": {
3 | "sess_GBEX1Qx0NXmSgXL1nPDg": {
4 | "Id": "sess_GBEX1Qx0NXmSgXL1nPDg",
5 | "UserId": "usr_CydtIC9KUZG0Cbjx",
6 | "Expiry": "2014-10-16T21:52:36.144147885+13:00"
7 | }
8 | }
9 | }
--------------------------------------------------------------------------------
/chapter3/7-unmarshaling-json/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "SiteName": "My Cat Blog",
3 | "SiteUrl": "www.mycatblog.com",
4 | "Database": {
5 | "Name": "cats",
6 | "Host": "localhost",
7 | "Port": 3306,
8 | "Username": "user1",
9 | "Password": "Password1"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter7/1_mysql/image.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "time"
4 |
5 | type Image struct {
6 | ID string
7 | UserID string
8 | Name string
9 | Location string
10 | Size int64
11 | CreatedAt time.Time
12 | Description string
13 | }
14 |
--------------------------------------------------------------------------------
/chapter7/2_db_image_store/image.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "time"
4 |
5 | type Image struct {
6 | ID string
7 | UserID string
8 | Name string
9 | Location string
10 | Size int64
11 | CreatedAt time.Time
12 | Description string
13 | }
14 |
--------------------------------------------------------------------------------
/ig/templates/sessions/destroy.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/destroy"}}
2 |
3 |
4 |
Signed Out
5 |
Thanks, you’re now signed out.
6 |
Login
7 |
8 |
9 | {{end}}
10 |
--------------------------------------------------------------------------------
/chapter10/0_base/templates/sessions/destroy.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/destroy"}}
2 |
3 |
4 |
Signed Out
5 |
Thanks, you’re now signed out.
6 |
Login
7 |
8 |
9 | {{end}}
10 |
--------------------------------------------------------------------------------
/chapter7/0_base/templates/sessions/destroy.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/destroy"}}
2 |
3 |
4 |
Signed Out
5 |
Thanks, you’re now signed out.
6 |
Login
7 |
8 |
9 | {{end}}
10 |
--------------------------------------------------------------------------------
/chapter7/1_mysql/templates/sessions/destroy.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/destroy"}}
2 |
3 |
4 |
Signed Out
5 |
Thanks, you’re now signed out.
6 |
Login
7 |
8 |
9 | {{end}}
10 |
--------------------------------------------------------------------------------
/chapter8/0_base/templates/sessions/destroy.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/destroy"}}
2 |
3 |
4 |
Signed Out
5 |
Thanks, you’re now signed out.
6 |
Login
7 |
8 |
9 | {{end}}
10 |
--------------------------------------------------------------------------------
/chapter9/0_base/templates/sessions/destroy.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/destroy"}}
2 |
3 |
4 |
Signed Out
5 |
Thanks, you’re now signed out.
6 |
Login
7 |
8 |
9 | {{end}}
10 |
--------------------------------------------------------------------------------
/ig/router.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func NewRouter() *httprouter.Router {
10 | router := httprouter.New()
11 | router.NotFound = func(http.ResponseWriter, *http.Request) {}
12 | return router
13 | }
14 |
--------------------------------------------------------------------------------
/chapter10/1_pkg_web/templates/sessions/destroy.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/destroy"}}
2 |
3 |
4 |
Signed Out
5 |
Thanks, you’re now signed out.
6 |
Login
7 |
8 |
9 | {{end}}
10 |
--------------------------------------------------------------------------------
/chapter10/2_godeps/templates/sessions/destroy.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/destroy"}}
2 |
3 |
4 |
Signed Out
5 |
Thanks, you’re now signed out.
6 |
Login
7 |
8 |
9 | {{end}}
10 |
--------------------------------------------------------------------------------
/chapter3/1-hello-world/hello.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "net/http"
6 | )
7 |
8 | func main() {
9 | http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
10 | fmt.Fprintf(w, "Hello Gopher")
11 | })
12 |
13 | http.ListenAndServe(":3000", nil)
14 | }
15 |
--------------------------------------------------------------------------------
/chapter6/6_edit_user/templates/sessions/destroy.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/destroy"}}
2 |
3 |
4 |
Signed Out
5 |
Thanks, you’re now signed out.
6 |
Login
7 |
8 |
9 | {{end}}
10 |
--------------------------------------------------------------------------------
/chapter7/2_db_image_store/templates/sessions/destroy.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/destroy"}}
2 |
3 |
4 |
Signed Out
5 |
Thanks, you’re now signed out.
6 |
Login
7 |
8 |
9 | {{end}}
10 |
--------------------------------------------------------------------------------
/chapter8/1_image_resizing/templates/sessions/destroy.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/destroy"}}
2 |
3 |
4 |
Signed Out
5 |
Thanks, you’re now signed out.
6 |
Login
7 |
8 |
9 | {{end}}
10 |
--------------------------------------------------------------------------------
/chapter8/2_display_resized/templates/sessions/destroy.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/destroy"}}
2 |
3 |
4 |
Signed Out
5 |
Thanks, you’re now signed out.
6 |
Login
7 |
8 |
9 | {{end}}
10 |
--------------------------------------------------------------------------------
/chapter9/2_mock_interface/templates/sessions/destroy.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/destroy"}}
2 |
3 |
4 |
Signed Out
5 |
Thanks, you’re now signed out.
6 |
Login
7 |
8 |
9 | {{end}}
10 |
--------------------------------------------------------------------------------
/chapter9/3_http_testing/templates/sessions/destroy.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/destroy"}}
2 |
3 |
4 |
Signed Out
5 |
Thanks, you’re now signed out.
6 |
Login
7 |
8 |
9 | {{end}}
10 |
--------------------------------------------------------------------------------
/chapter9/4_benchmarking/templates/sessions/destroy.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/destroy"}}
2 |
3 |
4 |
Signed Out
5 |
Thanks, you’re now signed out.
6 |
Login
7 |
8 |
9 | {{end}}
10 |
--------------------------------------------------------------------------------
/chapter6/5_signing_out_and_in/templates/sessions/destroy.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/destroy"}}
2 |
3 |
4 |
Signed Out
5 |
Thanks, you’re now signed out.
6 |
Login
7 |
8 |
9 | {{end}}
10 |
--------------------------------------------------------------------------------
/chapter7/3_uploading_images/templates/sessions/destroy.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/destroy"}}
2 |
3 |
4 |
Signed Out
5 |
Thanks, you’re now signed out.
6 |
Login
7 |
8 |
9 | {{end}}
10 |
--------------------------------------------------------------------------------
/chapter7/4_displaying_images/templates/sessions/destroy.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/destroy"}}
2 |
3 |
4 |
Signed Out
5 |
Thanks, you’re now signed out.
6 |
Login
7 |
8 |
9 | {{end}}
10 |
--------------------------------------------------------------------------------
/chapter9/1_simple_input_tests/templates/sessions/destroy.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/destroy"}}
2 |
3 |
4 |
Signed Out
5 |
Thanks, you’re now signed out.
6 |
Login
7 |
8 |
9 | {{end}}
10 |
--------------------------------------------------------------------------------
/chapter5/0_base/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | RenderTemplate(w, r, "index/home", nil)
12 | }
13 |
--------------------------------------------------------------------------------
/chapter5/1_router/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | RenderTemplate(w, r, "index/home", nil)
12 | }
13 |
--------------------------------------------------------------------------------
/chapter6/0_base/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | RenderTemplate(w, r, "index/home", nil)
12 | }
13 |
--------------------------------------------------------------------------------
/chapter6/1_new_session/data/users.json:
--------------------------------------------------------------------------------
1 | {
2 | "Users": {
3 | "usr_xddHcUI0OuRlrREv": {
4 | "Id": "usr_xddHcUI0OuRlrREv",
5 | "Email": "mal@mal.co.nz",
6 | "HashedPassword": "$2a$10$1y2ojzbG8lCDR6rkydh4l.Y0cBngvXOlpK7HGnA3X4E9AP3dNmVpy",
7 | "Username": "mal"
8 | }
9 | }
10 | }
--------------------------------------------------------------------------------
/chapter6/6_edit_user/data/users.json:
--------------------------------------------------------------------------------
1 | {
2 | "Users": {
3 | "usr_ZRtM7bsqwge7ooxU": {
4 | "Id": "usr_ZRtM7bsqwge7ooxU",
5 | "Email": "ma1l@mal.co.nz",
6 | "HashedPassword": "$2a$10$MUjtyTQW9blr/vz3hGydN.anyUFdiDUZfHE36.GGgzt4VgJaiGb0W",
7 | "Username": "mal"
8 | }
9 | }
10 | }
--------------------------------------------------------------------------------
/chapter7/0_base/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | RenderTemplate(w, r, "index/home", nil)
12 | }
13 |
--------------------------------------------------------------------------------
/chapter7/1_mysql/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | RenderTemplate(w, r, "index/home", nil)
12 | }
13 |
--------------------------------------------------------------------------------
/chapter4/4_httprouter/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | RenderTemplate(w, r, "index/home", nil)
12 | }
13 |
--------------------------------------------------------------------------------
/chapter4/4_httprouter/handle_user.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleUserNew(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | RenderTemplate(w, r, "users/new", nil)
12 | }
13 |
--------------------------------------------------------------------------------
/chapter5/2_registration/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | RenderTemplate(w, r, "index/home", nil)
12 | }
13 |
--------------------------------------------------------------------------------
/chapter5/3_user_store/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | RenderTemplate(w, r, "index/home", nil)
12 | }
13 |
--------------------------------------------------------------------------------
/chapter6/1_new_session/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | RenderTemplate(w, r, "index/home", nil)
12 | }
13 |
--------------------------------------------------------------------------------
/chapter6/2_session_store/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | RenderTemplate(w, r, "index/home", nil)
12 | }
13 |
--------------------------------------------------------------------------------
/chapter6/3_require_login/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | RenderTemplate(w, r, "index/home", nil)
12 | }
13 |
--------------------------------------------------------------------------------
/chapter6/4_template_data/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | RenderTemplate(w, r, "index/home", nil)
12 | }
13 |
--------------------------------------------------------------------------------
/chapter6/5_signing_out_and_in/data/users.json:
--------------------------------------------------------------------------------
1 | {
2 | "Users": {
3 | "usr_ZRtM7bsqwge7ooxU": {
4 | "Id": "usr_ZRtM7bsqwge7ooxU",
5 | "Email": "mal@mal.co.nz",
6 | "HashedPassword": "$2a$10$jYF3DAoKVNV/X9jBqDUYXec2wloiq4/yFn5s55E9cce.MAxRT9Pbq",
7 | "Username": "mal"
8 | }
9 | }
10 | }
--------------------------------------------------------------------------------
/chapter6/6_edit_user/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | RenderTemplate(w, r, "index/home", nil)
12 | }
13 |
--------------------------------------------------------------------------------
/chapter6/5_signing_out_and_in/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | RenderTemplate(w, r, "index/home", nil)
12 | }
13 |
--------------------------------------------------------------------------------
/chapter7/2_db_image_store/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | RenderTemplate(w, r, "index/home", nil)
12 | }
13 |
--------------------------------------------------------------------------------
/chapter7/3_uploading_images/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | RenderTemplate(w, r, "index/home", nil)
12 | }
13 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # “Level Up Your Web Apps With Go” Code Archive
2 |
3 | This repository contains the code archive for the SitePoint books [Level Up Your Web Apps With Go](https://www.sitepoint.com/premium/books/level-up-your-web-apps-with-go). Please follow along with the book, as some code may not compile without additional information.
4 |
--------------------------------------------------------------------------------
/chapter10/0_base/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter5/0_base/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter6/0_base/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter7/0_base/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter7/1_mysql/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter8/0_base/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter9/0_base/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter10/1_pkg_web/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter10/2_godeps/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter4/4_httprouter/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter5/1_router/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter5/3_user_store/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter6/6_edit_user/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ig/handle_frontpage.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func HandleFrontpage(w http.ResponseWriter, r *http.Request) {
6 | images, err := globalImageStore.FindAll(0)
7 | if err != nil {
8 | panic(err)
9 | }
10 | RenderTemplate(w, r, "index/home", map[string]interface{}{
11 | "Images": images,
12 | })
13 | }
14 |
--------------------------------------------------------------------------------
/chapter2/markdown.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/russross/blackfriday"
7 | )
8 |
9 | func main() {
10 | markdown := []byte(`
11 | # This is a header
12 | * and
13 | * this
14 | * is
15 | * a
16 | * list
17 | `)
18 | html := blackfriday.MarkdownBasic(markdown)
19 | fmt.Println(string(html))
20 | }
21 |
--------------------------------------------------------------------------------
/chapter5/2_registration/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter6/1_new_session/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter6/2_session_store/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter6/3_require_login/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter6/4_template_data/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter7/2_db_image_store/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter8/1_image_resizing/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter8/2_display_resized/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter9/2_mock_interface/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter9/3_http_testing/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter9/4_benchmarking/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter4/1_file_server/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "net/http"
6 | )
7 |
8 | func main() {
9 | // Simple static webserver:
10 | mux := http.NewServeMux()
11 | mux.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("assets/"))))
12 |
13 | log.Fatal(http.ListenAndServe(":3000", mux))
14 | }
15 |
--------------------------------------------------------------------------------
/chapter4/4_httprouter/handle_image.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "net/http"
6 |
7 | "github.com/julienschmidt/httprouter"
8 | )
9 |
10 | func HandleImageNew(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
11 | // Display New Image Form
12 | panic(fmt.Errorf("This should not be reached!"))
13 | }
14 |
--------------------------------------------------------------------------------
/chapter6/5_signing_out_and_in/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter7/3_uploading_images/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter7/4_displaying_images/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter9/1_simple_input_tests/auth.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func AuthenticateRequest(w http.ResponseWriter, r *http.Request) {
6 | // Redirect the user to login if they’re not authenticated
7 | authenticated := false
8 | if !authenticated {
9 | http.Redirect(w, r, "/register", http.StatusFound)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/chapter5/0_base/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func main() {
10 | }
11 |
12 | // Creates a new router
13 | func NewRouter() *httprouter.Router {
14 | router := httprouter.New()
15 | router.NotFound = func(http.ResponseWriter, *http.Request) {}
16 | return router
17 | }
18 |
--------------------------------------------------------------------------------
/chapter10/0_base/mysql.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "database/sql"
5 |
6 | _ "github.com/go-sql-driver/mysql"
7 | )
8 |
9 | var globalMySQLDB *sql.DB
10 |
11 | func NewMySQLDB(dsn string) (*sql.DB, error) {
12 | db, err := sql.Open("mysql", dsn+"?parseTime=true")
13 | if err != nil {
14 | return nil, err
15 | }
16 |
17 | return db, db.Ping()
18 | }
19 |
--------------------------------------------------------------------------------
/chapter10/1_pkg_web/mysql.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "database/sql"
5 |
6 | _ "github.com/go-sql-driver/mysql"
7 | )
8 |
9 | var globalMySQLDB *sql.DB
10 |
11 | func NewMySQLDB(dsn string) (*sql.DB, error) {
12 | db, err := sql.Open("mysql", dsn+"?parseTime=true")
13 | if err != nil {
14 | return nil, err
15 | }
16 |
17 | return db, db.Ping()
18 | }
19 |
--------------------------------------------------------------------------------
/chapter10/2_godeps/mysql.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "database/sql"
5 |
6 | _ "github.com/go-sql-driver/mysql"
7 | )
8 |
9 | var globalMySQLDB *sql.DB
10 |
11 | func NewMySQLDB(dsn string) (*sql.DB, error) {
12 | db, err := sql.Open("mysql", dsn+"?parseTime=true")
13 | if err != nil {
14 | return nil, err
15 | }
16 |
17 | return db, db.Ping()
18 | }
19 |
--------------------------------------------------------------------------------
/chapter8/0_base/mysql.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "database/sql"
5 |
6 | _ "github.com/go-sql-driver/mysql"
7 | )
8 |
9 | var globalMySQLDB *sql.DB
10 |
11 | func NewMySQLDB(dsn string) (*sql.DB, error) {
12 | db, err := sql.Open("mysql", dsn+"?parseTime=true")
13 | if err != nil {
14 | return nil, err
15 | }
16 |
17 | return db, db.Ping()
18 | }
19 |
--------------------------------------------------------------------------------
/chapter9/0_base/mysql.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "database/sql"
5 |
6 | _ "github.com/go-sql-driver/mysql"
7 | )
8 |
9 | var globalMySQLDB *sql.DB
10 |
11 | func NewMySQLDB(dsn string) (*sql.DB, error) {
12 | db, err := sql.Open("mysql", dsn+"?parseTime=true")
13 | if err != nil {
14 | return nil, err
15 | }
16 |
17 | return db, db.Ping()
18 | }
19 |
--------------------------------------------------------------------------------
/chapter9/3_http_testing/mysql.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "database/sql"
5 |
6 | _ "github.com/go-sql-driver/mysql"
7 | )
8 |
9 | var globalMySQLDB *sql.DB
10 |
11 | func NewMySQLDB(dsn string) (*sql.DB, error) {
12 | db, err := sql.Open("mysql", dsn+"?parseTime=true")
13 | if err != nil {
14 | return nil, err
15 | }
16 |
17 | return db, db.Ping()
18 | }
19 |
--------------------------------------------------------------------------------
/chapter9/4_benchmarking/mysql.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "database/sql"
5 |
6 | _ "github.com/go-sql-driver/mysql"
7 | )
8 |
9 | var globalMySQLDB *sql.DB
10 |
11 | func NewMySQLDB(dsn string) (*sql.DB, error) {
12 | db, err := sql.Open("mysql", dsn+"?parseTime=true")
13 | if err != nil {
14 | return nil, err
15 | }
16 |
17 | return db, db.Ping()
18 | }
19 |
--------------------------------------------------------------------------------
/chapter7/2_db_image_store/mysql.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "database/sql"
5 |
6 | _ "github.com/go-sql-driver/mysql"
7 | )
8 |
9 | var globalMySQLDB *sql.DB
10 |
11 | func NewMySQLDB(dsn string) (*sql.DB, error) {
12 | db, err := sql.Open("mysql", dsn+"?parseTime=true")
13 | if err != nil {
14 | return nil, err
15 | }
16 |
17 | return db, db.Ping()
18 | }
19 |
--------------------------------------------------------------------------------
/chapter7/3_uploading_images/mysql.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "database/sql"
5 |
6 | _ "github.com/go-sql-driver/mysql"
7 | )
8 |
9 | var globalMySQLDB *sql.DB
10 |
11 | func NewMySQLDB(dsn string) (*sql.DB, error) {
12 | db, err := sql.Open("mysql", dsn+"?parseTime=true")
13 | if err != nil {
14 | return nil, err
15 | }
16 |
17 | return db, db.Ping()
18 | }
19 |
--------------------------------------------------------------------------------
/chapter7/4_displaying_images/mysql.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "database/sql"
5 |
6 | _ "github.com/go-sql-driver/mysql"
7 | )
8 |
9 | var globalMySQLDB *sql.DB
10 |
11 | func NewMySQLDB(dsn string) (*sql.DB, error) {
12 | db, err := sql.Open("mysql", dsn+"?parseTime=true")
13 | if err != nil {
14 | return nil, err
15 | }
16 |
17 | return db, db.Ping()
18 | }
19 |
--------------------------------------------------------------------------------
/chapter8/1_image_resizing/mysql.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "database/sql"
5 |
6 | _ "github.com/go-sql-driver/mysql"
7 | )
8 |
9 | var globalMySQLDB *sql.DB
10 |
11 | func NewMySQLDB(dsn string) (*sql.DB, error) {
12 | db, err := sql.Open("mysql", dsn+"?parseTime=true")
13 | if err != nil {
14 | return nil, err
15 | }
16 |
17 | return db, db.Ping()
18 | }
19 |
--------------------------------------------------------------------------------
/chapter8/2_display_resized/mysql.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "database/sql"
5 |
6 | _ "github.com/go-sql-driver/mysql"
7 | )
8 |
9 | var globalMySQLDB *sql.DB
10 |
11 | func NewMySQLDB(dsn string) (*sql.DB, error) {
12 | db, err := sql.Open("mysql", dsn+"?parseTime=true")
13 | if err != nil {
14 | return nil, err
15 | }
16 |
17 | return db, db.Ping()
18 | }
19 |
--------------------------------------------------------------------------------
/chapter9/1_simple_input_tests/mysql.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "database/sql"
5 |
6 | _ "github.com/go-sql-driver/mysql"
7 | )
8 |
9 | var globalMySQLDB *sql.DB
10 |
11 | func NewMySQLDB(dsn string) (*sql.DB, error) {
12 | db, err := sql.Open("mysql", dsn+"?parseTime=true")
13 | if err != nil {
14 | return nil, err
15 | }
16 |
17 | return db, db.Ping()
18 | }
19 |
--------------------------------------------------------------------------------
/chapter9/2_mock_interface/mysql.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "database/sql"
5 |
6 | _ "github.com/go-sql-driver/mysql"
7 | )
8 |
9 | var globalMySQLDB *sql.DB
10 |
11 | func NewMySQLDB(dsn string) (*sql.DB, error) {
12 | db, err := sql.Open("mysql", dsn+"?parseTime=true")
13 | if err != nil {
14 | return nil, err
15 | }
16 |
17 | return db, db.Ping()
18 | }
19 |
--------------------------------------------------------------------------------
/ig/response.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func Handle404(w http.ResponseWriter, r *http.Request) {
6 | http.NotFound(w, r)
7 | }
8 |
9 | func RenderError(w http.ResponseWriter, r *http.Request, err error) {
10 | w.WriteHeader(http.StatusInternalServerError)
11 | RenderTemplate(w, r, "errors/500", map[string]interface{}{
12 | "Error": err.Error(),
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/chapter3/2-extra-headers/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "net/http"
6 | )
7 |
8 | func main() {
9 | http.HandleFunc("/foo", func(w http.ResponseWriter, r *http.Request) {
10 | w.Header().Add("Server", "Go Server")
11 | fmt.Fprintf(w, `
12 |
13 |
14 | Hello Gopher
15 |
16 | `)
17 | })
18 |
19 | http.ListenAndServe(":3000", nil)
20 | }
21 |
--------------------------------------------------------------------------------
/chapter4/3_layouts/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func main() {
6 | mux := http.NewServeMux()
7 |
8 | mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
9 | RenderTemplate(w, r, "index/home", nil)
10 | })
11 |
12 | mux.Handle(
13 | "/assets/",
14 | http.StripPrefix("/assets/", http.FileServer(http.Dir("assets/"))),
15 | )
16 |
17 | http.ListenAndServe(":3000", mux)
18 | }
19 |
--------------------------------------------------------------------------------
/chapter4/2_first_template/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func main() {
6 | mux := http.NewServeMux()
7 |
8 | mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
9 | RenderTemplate(w, r, "index/home", nil)
10 | })
11 |
12 | mux.Handle(
13 | "/assets/",
14 | http.StripPrefix("/assets/", http.FileServer(http.Dir("assets/"))),
15 | )
16 |
17 | http.ListenAndServe(":3000", mux)
18 | }
19 |
--------------------------------------------------------------------------------
/ig/templates/images/index.html:
--------------------------------------------------------------------------------
1 | {{define "images/index"}}
2 |
3 | {{if .Images}}
4 | {{range .Images}}
5 |
10 | {{end}}
11 | {{else}}
12 |
No Images Yet
13 |
Why not upload one?
14 | {{end}}
15 |
16 | {{end}}
17 |
--------------------------------------------------------------------------------
/chapter8/0_base/templates/images/index.html:
--------------------------------------------------------------------------------
1 | {{define "images/index"}}
2 |
3 | {{if .Images}}
4 | {{range .Images}}
5 |
10 | {{end}}
11 | {{else}}
12 |
No Images Yet
13 |
Why not upload one?
14 | {{end}}
15 |
16 | {{end}}
17 |
--------------------------------------------------------------------------------
/chapter10/0_base/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | images, err := globalImageStore.FindAll(0)
12 | if err != nil {
13 | panic(err)
14 | }
15 | RenderTemplate(w, r, "index/home", map[string]interface{}{
16 | "Images": images,
17 | })
18 | }
19 |
--------------------------------------------------------------------------------
/chapter10/1_pkg_web/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | images, err := globalImageStore.FindAll(0)
12 | if err != nil {
13 | panic(err)
14 | }
15 | RenderTemplate(w, r, "index/home", map[string]interface{}{
16 | "Images": images,
17 | })
18 | }
19 |
--------------------------------------------------------------------------------
/chapter10/2_godeps/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | images, err := globalImageStore.FindAll(0)
12 | if err != nil {
13 | panic(err)
14 | }
15 | RenderTemplate(w, r, "index/home", map[string]interface{}{
16 | "Images": images,
17 | })
18 | }
19 |
--------------------------------------------------------------------------------
/chapter8/0_base/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | images, err := globalImageStore.FindAll(0)
12 | if err != nil {
13 | panic(err)
14 | }
15 | RenderTemplate(w, r, "index/home", map[string]interface{}{
16 | "Images": images,
17 | })
18 | }
19 |
--------------------------------------------------------------------------------
/chapter9/0_base/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | images, err := globalImageStore.FindAll(0)
12 | if err != nil {
13 | panic(err)
14 | }
15 | RenderTemplate(w, r, "index/home", map[string]interface{}{
16 | "Images": images,
17 | })
18 | }
19 |
--------------------------------------------------------------------------------
/chapter10/0_base/templates/images/index.html:
--------------------------------------------------------------------------------
1 | {{define "images/index"}}
2 |
3 | {{if .Images}}
4 | {{range .Images}}
5 |
10 | {{end}}
11 | {{else}}
12 |
No Images Yet
13 |
Why not upload one?
14 | {{end}}
15 |
16 | {{end}}
17 |
--------------------------------------------------------------------------------
/chapter10/examples/2_exporting_values/foo/foo.go:
--------------------------------------------------------------------------------
1 | package foo
2 |
3 | import "fmt"
4 |
5 | type Bar struct {
6 | Visible bool
7 | hidden bool
8 | }
9 |
10 | func NewBar() Bar {
11 | return Bar{
12 | Visible: true,
13 | hidden: true,
14 | }
15 | }
16 |
17 | func (bar Bar) String() string {
18 | return bar.status()
19 | }
20 | func (bar Bar) status() string {
21 | return fmt.Sprintf("Visible is %T and hidden is %T", bar.Visible, bar.hidden)
22 | }
23 |
--------------------------------------------------------------------------------
/chapter8/1_image_resizing/templates/images/index.html:
--------------------------------------------------------------------------------
1 | {{define "images/index"}}
2 |
3 | {{if .Images}}
4 | {{range .Images}}
5 |
10 | {{end}}
11 | {{else}}
12 |
No Images Yet
13 |
Why not upload one?
14 | {{end}}
15 |
16 | {{end}}
17 |
--------------------------------------------------------------------------------
/chapter9/0_base/templates/images/index.html:
--------------------------------------------------------------------------------
1 | {{define "images/index"}}
2 |
3 | {{if .Images}}
4 | {{range .Images}}
5 |
10 | {{end}}
11 | {{else}}
12 |
No Images Yet
13 |
Why not upload one?
14 | {{end}}
15 |
16 | {{end}}
17 |
--------------------------------------------------------------------------------
/chapter9/3_http_testing/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | images, err := globalImageStore.FindAll(0)
12 | if err != nil {
13 | panic(err)
14 | }
15 | RenderTemplate(w, r, "index/home", map[string]interface{}{
16 | "Images": images,
17 | })
18 | }
19 |
--------------------------------------------------------------------------------
/chapter9/4_benchmarking/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | images, err := globalImageStore.FindAll(0)
12 | if err != nil {
13 | panic(err)
14 | }
15 | RenderTemplate(w, r, "index/home", map[string]interface{}{
16 | "Images": images,
17 | })
18 | }
19 |
--------------------------------------------------------------------------------
/chapter9/examples/1_addition/addition_test.go:
--------------------------------------------------------------------------------
1 | // addition_test.go
2 | package main
3 |
4 | import "testing"
5 |
6 | func TestOnePlusOne(t *testing.T) {
7 | onePlusOne := 1 + 1
8 | if onePlusOne != 2 {
9 | t.Error("Expected 1 + 1 to equal 2, but got", onePlusOne)
10 | }
11 | }
12 |
13 | func TestTwoPlusTwo(t *testing.T) {
14 | twoPlusTwo := 2 + 2
15 | if twoPlusTwo != 4 {
16 | t.Error("Expected 2 + 2 to equal 4, but got", twoPlusTwo)
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/chapter10/1_pkg_web/templates/images/index.html:
--------------------------------------------------------------------------------
1 | {{define "images/index"}}
2 |
3 | {{if .Images}}
4 | {{range .Images}}
5 |
10 | {{end}}
11 | {{else}}
12 |
No Images Yet
13 |
Why not upload one?
14 | {{end}}
15 |
16 | {{end}}
17 |
--------------------------------------------------------------------------------
/chapter10/2_godeps/templates/images/index.html:
--------------------------------------------------------------------------------
1 | {{define "images/index"}}
2 |
3 | {{if .Images}}
4 | {{range .Images}}
5 |
10 | {{end}}
11 | {{else}}
12 |
No Images Yet
13 |
Why not upload one?
14 | {{end}}
15 |
16 | {{end}}
17 |
--------------------------------------------------------------------------------
/chapter7/4_displaying_images/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | images, err := globalImageStore.FindAll(0)
12 | if err != nil {
13 | panic(err)
14 | }
15 | RenderTemplate(w, r, "index/home", map[string]interface{}{
16 | "Images": images,
17 | })
18 | }
19 |
--------------------------------------------------------------------------------
/chapter7/4_displaying_images/templates/images/index.html:
--------------------------------------------------------------------------------
1 | {{define "images/index"}}
2 |
3 | {{if .Images}}
4 | {{range .Images}}
5 |
10 | {{end}}
11 | {{else}}
12 |
No Images Yet
13 |
Why not upload one?
14 | {{end}}
15 |
16 | {{end}}
17 |
--------------------------------------------------------------------------------
/chapter8/1_image_resizing/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | images, err := globalImageStore.FindAll(0)
12 | if err != nil {
13 | panic(err)
14 | }
15 | RenderTemplate(w, r, "index/home", map[string]interface{}{
16 | "Images": images,
17 | })
18 | }
19 |
--------------------------------------------------------------------------------
/chapter8/2_display_resized/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | images, err := globalImageStore.FindAll(0)
12 | if err != nil {
13 | panic(err)
14 | }
15 | RenderTemplate(w, r, "index/home", map[string]interface{}{
16 | "Images": images,
17 | })
18 | }
19 |
--------------------------------------------------------------------------------
/chapter9/1_simple_input_tests/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | images, err := globalImageStore.FindAll(0)
12 | if err != nil {
13 | panic(err)
14 | }
15 | RenderTemplate(w, r, "index/home", map[string]interface{}{
16 | "Images": images,
17 | })
18 | }
19 |
--------------------------------------------------------------------------------
/chapter9/2_mock_interface/handle_index.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleHome(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
10 | // Display Home Page
11 | images, err := globalImageStore.FindAll(0)
12 | if err != nil {
13 | panic(err)
14 | }
15 | RenderTemplate(w, r, "index/home", map[string]interface{}{
16 | "Images": images,
17 | })
18 | }
19 |
--------------------------------------------------------------------------------
/chapter4/3_layouts/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 |
3 |
13 |
14 | {{end}}
15 |
--------------------------------------------------------------------------------
/chapter6/4_template_data/data/sessions.json:
--------------------------------------------------------------------------------
1 | {
2 | "Sessions": {
3 | "sess_GBEX1Qx0NXmSgXL1nPDg": {
4 | "Id": "sess_GBEX1Qx0NXmSgXL1nPDg",
5 | "UserId": "usr_CydtIC9KUZG0Cbjx",
6 | "Expiry": "2014-10-16T21:52:36.144147885+13:00"
7 | },
8 | "sess_UZA8Sihz7VQ7isxoedFE": {
9 | "Id": "sess_UZA8Sihz7VQ7isxoedFE",
10 | "UserId": "usr_Bw5ctWmCcko8fzIS",
11 | "Expiry": "2014-11-12T10:51:49.412724459+13:00"
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/chapter8/2_display_resized/templates/images/index.html:
--------------------------------------------------------------------------------
1 | {{define "images/index"}}
2 |
3 | {{if .Images}}
4 | {{range .Images}}
5 |
10 | {{end}}
11 | {{else}}
12 |
No Images Yet
13 |
Why not upload one?
14 | {{end}}
15 |
16 | {{end}}
17 |
--------------------------------------------------------------------------------
/chapter9/2_mock_interface/templates/images/index.html:
--------------------------------------------------------------------------------
1 | {{define "images/index"}}
2 |
3 | {{if .Images}}
4 | {{range .Images}}
5 |
10 | {{end}}
11 | {{else}}
12 |
No Images Yet
13 |
Why not upload one?
14 | {{end}}
15 |
16 | {{end}}
17 |
--------------------------------------------------------------------------------
/chapter9/3_http_testing/templates/images/index.html:
--------------------------------------------------------------------------------
1 | {{define "images/index"}}
2 |
3 | {{if .Images}}
4 | {{range .Images}}
5 |
10 | {{end}}
11 | {{else}}
12 |
No Images Yet
13 |
Why not upload one?
14 | {{end}}
15 |
16 | {{end}}
17 |
--------------------------------------------------------------------------------
/chapter9/4_benchmarking/templates/images/index.html:
--------------------------------------------------------------------------------
1 | {{define "images/index"}}
2 |
3 | {{if .Images}}
4 | {{range .Images}}
5 |
10 | {{end}}
11 | {{else}}
12 |
No Images Yet
13 |
Why not upload one?
14 | {{end}}
15 |
16 | {{end}}
17 |
--------------------------------------------------------------------------------
/chapter4/4_httprouter/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 |
3 |
13 |
14 | {{end}}
15 |
--------------------------------------------------------------------------------
/chapter9/1_simple_input_tests/templates/images/index.html:
--------------------------------------------------------------------------------
1 | {{define "images/index"}}
2 |
3 | {{if .Images}}
4 | {{range .Images}}
5 |
10 | {{end}}
11 | {{else}}
12 |
No Images Yet
13 |
Why not upload one?
14 | {{end}}
15 |
16 | {{end}}
17 |
--------------------------------------------------------------------------------
/chapter1/starwars.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | starWarsYears := map[string]int{
7 | "A New Hope": 1977,
8 | "The Empire Strikes Back": 1980,
9 | "Return of the Jedi": 1983,
10 | "Attack of the Clones": 2002,
11 | "Revenge of the Sith": 2005,
12 | }
13 | starWarsYears["The Force Awakens"] = 2015
14 |
15 | for title, year := range starWarsYears {
16 | fmt.Println(title, "was released in", year)
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/chapter9/1_simple_input_tests/user_test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "testing"
4 |
5 | func TestNewUserNoUsername(t *testing.T) {
6 | _, err := NewUser("", "user@example.com", "password")
7 | if err != errNoUsername {
8 | t.Error("Expected err to be errNoUsername")
9 | }
10 | }
11 |
12 | func TestNewUserNoPassword(t *testing.T) {
13 | _, err := NewUser("user", "user@example.com", "")
14 | if err != errNoPassword {
15 | t.Error("Expected err to be errNoUsername")
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/chapter9/examples/2_wrapper_functions/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "io/ioutil"
5 | "os"
6 | )
7 |
8 | func main() {
9 | str := "How do I test this message is being written?"
10 | loc := "test.txt"
11 | err := WriteStuff(str, loc)
12 | if err != nil {
13 | panic(err)
14 | }
15 | }
16 |
17 | func WriteStuff(str, loc string) error {
18 | err := writeFile(loc, []byte(str), os.ModeAppend)
19 | if err != nil {
20 | return err
21 | }
22 | return nil
23 | }
24 |
25 | var writeFile = ioutil.WriteFile
26 |
--------------------------------------------------------------------------------
/ig/mysql.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "database/sql"
5 |
6 | _ "github.com/go-sql-driver/mysql"
7 | )
8 |
9 | var globalMySQLDB *sql.DB
10 |
11 | func init() {
12 | db, err := NewMySQLDB("root:root@tcp(127.0.0.1:3306)/gophr")
13 | if err != nil {
14 | panic(err)
15 | }
16 | globalMySQLDB = db
17 | }
18 |
19 | func NewMySQLDB(dsn string) (*sql.DB, error) {
20 | db, err := sql.Open("mysql", dsn+"?parseTime=true")
21 | if err != nil {
22 | return nil, err
23 | }
24 |
25 | return db, db.Ping()
26 | }
27 |
--------------------------------------------------------------------------------
/ig/data/users.json:
--------------------------------------------------------------------------------
1 | {
2 | "Users": {
3 | "usr_Mp8ry7c6D4dUuPCd": {
4 | "ID": "usr_Mp8ry7c6D4dUuPCd",
5 | "Email": "mal2@mal.co.nz",
6 | "HashedPassword": "$2a$10$YC/GQMgxWiomR2Yi1kgZvu3hK7AMjfev.47Xd95r1UVGVFKpF2NX6",
7 | "Username": "NotMal"
8 | },
9 | "usr_UvfFNCUI2pp3fLIh": {
10 | "ID": "usr_UvfFNCUI2pp3fLIh",
11 | "Email": "mal@mal.co.nz",
12 | "HashedPassword": "$2a$10$hd49NkCFrkoI2sjd9o28S.lvzTG764dXZQYFRe4zcsOozRvfih5C.",
13 | "Username": "mal"
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/chapter7/1_mysql/mysql.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "database/sql"
5 |
6 | _ "github.com/go-sql-driver/mysql"
7 | )
8 |
9 | var globalMySQLDB *sql.DB
10 |
11 | func init() {
12 | db, err := NewMySQLDB("root:root@tcp(127.0.0.1:3306)/gophr")
13 | if err != nil {
14 | panic(err)
15 | }
16 | globalMySQLDB = db
17 | }
18 |
19 | func NewMySQLDB(dsn string) (*sql.DB, error) {
20 | db, err := sql.Open("mysql", dsn+"?parseTime=true")
21 | if err != nil {
22 | return nil, err
23 | }
24 |
25 | return db, db.Ping()
26 | }
27 |
--------------------------------------------------------------------------------
/chapter5/2_registration/errors.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "errors"
4 |
5 | type ValidationError error
6 |
7 | var (
8 | errNoUsername = ValidationError(errors.New("You must supply a username"))
9 | errNoEmail = ValidationError(errors.New("You must supply an email"))
10 | errNoPassword = ValidationError(errors.New("You must supply a password"))
11 | errPasswordTooShort = ValidationError(errors.New("Your password is too short"))
12 | )
13 |
14 | func IsValidationError(err error) bool {
15 | _, ok := err.(ValidationError)
16 | return ok
17 | }
18 |
--------------------------------------------------------------------------------
/ig/templates/users/show.html:
--------------------------------------------------------------------------------
1 | {{define "users/show"}}
2 |
19 | {{template "images/index" .}}
20 | {{end}}
21 |
--------------------------------------------------------------------------------
/chapter5/0_base/templates/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
17 |
18 | {{ yield }}
19 |
20 |
21 |
--------------------------------------------------------------------------------
/chapter5/1_router/templates/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
17 |
18 | {{ yield }}
19 |
20 |
21 |
--------------------------------------------------------------------------------
/chapter6/0_base/templates/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
17 |
18 | {{ yield }}
19 |
20 |
21 |
--------------------------------------------------------------------------------
/chapter5/3_user_store/templates/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
17 |
18 | {{ yield }}
19 |
20 |
21 |
--------------------------------------------------------------------------------
/chapter6/1_new_session/templates/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
17 |
18 | {{ yield }}
19 |
20 |
21 |
--------------------------------------------------------------------------------
/chapter8/0_base/templates/users/show.html:
--------------------------------------------------------------------------------
1 | {{define "users/show"}}
2 |
19 | {{template "images/index" .}}
20 | {{end}}
21 |
--------------------------------------------------------------------------------
/chapter9/0_base/templates/users/show.html:
--------------------------------------------------------------------------------
1 | {{define "users/show"}}
2 |
19 | {{template "images/index" .}}
20 | {{end}}
21 |
--------------------------------------------------------------------------------
/chapter10/0_base/templates/users/show.html:
--------------------------------------------------------------------------------
1 | {{define "users/show"}}
2 |
19 | {{template "images/index" .}}
20 | {{end}}
21 |
--------------------------------------------------------------------------------
/chapter10/1_pkg_web/templates/users/show.html:
--------------------------------------------------------------------------------
1 | {{define "users/show"}}
2 |
19 | {{template "images/index" .}}
20 | {{end}}
21 |
--------------------------------------------------------------------------------
/chapter10/2_godeps/templates/users/show.html:
--------------------------------------------------------------------------------
1 | {{define "users/show"}}
2 |
19 | {{template "images/index" .}}
20 | {{end}}
21 |
--------------------------------------------------------------------------------
/chapter5/2_registration/templates/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
17 |
18 | {{ yield }}
19 |
20 |
21 |
--------------------------------------------------------------------------------
/chapter6/2_session_store/templates/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
17 |
18 | {{ yield }}
19 |
20 |
21 |
--------------------------------------------------------------------------------
/chapter6/3_require_login/templates/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
17 |
18 | {{ yield }}
19 |
20 |
21 |
--------------------------------------------------------------------------------
/chapter8/1_image_resizing/templates/users/show.html:
--------------------------------------------------------------------------------
1 | {{define "users/show"}}
2 |
19 | {{template "images/index" .}}
20 | {{end}}
21 |
--------------------------------------------------------------------------------
/chapter9/2_mock_interface/templates/users/show.html:
--------------------------------------------------------------------------------
1 | {{define "users/show"}}
2 |
19 | {{template "images/index" .}}
20 | {{end}}
21 |
--------------------------------------------------------------------------------
/chapter9/3_http_testing/templates/users/show.html:
--------------------------------------------------------------------------------
1 | {{define "users/show"}}
2 |
19 | {{template "images/index" .}}
20 | {{end}}
21 |
--------------------------------------------------------------------------------
/chapter9/4_benchmarking/templates/users/show.html:
--------------------------------------------------------------------------------
1 | {{define "users/show"}}
2 |
19 | {{template "images/index" .}}
20 | {{end}}
21 |
--------------------------------------------------------------------------------
/chapter7/4_displaying_images/templates/users/show.html:
--------------------------------------------------------------------------------
1 | {{define "users/show"}}
2 |
19 | {{template "images/index" .}}
20 | {{end}}
21 |
--------------------------------------------------------------------------------
/chapter8/2_display_resized/templates/users/show.html:
--------------------------------------------------------------------------------
1 | {{define "users/show"}}
2 |
19 | {{template "images/index" .}}
20 | {{end}}
21 |
--------------------------------------------------------------------------------
/chapter9/1_simple_input_tests/templates/users/show.html:
--------------------------------------------------------------------------------
1 | {{define "users/show"}}
2 |
19 | {{template "images/index" .}}
20 | {{end}}
21 |
--------------------------------------------------------------------------------
/chapter10/2_godeps/Godeps/_workspace/src/github.com/go-sql-driver/mysql/appengine.go:
--------------------------------------------------------------------------------
1 | // Go MySQL Driver - A MySQL-Driver for Go's database/sql package
2 | //
3 | // Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved.
4 | //
5 | // This Source Code Form is subject to the terms of the Mozilla Public
6 | // License, v. 2.0. If a copy of the MPL was not distributed with this file,
7 | // You can obtain one at http://mozilla.org/MPL/2.0/.
8 |
9 | // +build appengine
10 |
11 | package mysql
12 |
13 | import (
14 | "appengine/cloudsql"
15 | )
16 |
17 | func init() {
18 | RegisterDial("cloudsql", cloudsql.Dial)
19 | }
20 |
--------------------------------------------------------------------------------
/chapter4/2_first_template/templates/index/home.html:
--------------------------------------------------------------------------------
1 | {{define "index/home"}}
2 |
3 |
4 |
5 |
6 |
7 |
8 |
18 |
19 |
20 |
21 | {{end}}
22 |
--------------------------------------------------------------------------------
/chapter6/6_edit_user/data/sessions.json:
--------------------------------------------------------------------------------
1 | {
2 | "Sessions": {
3 | "sess_GBEX1Qx0NXmSgXL1nPDg": {
4 | "Id": "sess_GBEX1Qx0NXmSgXL1nPDg",
5 | "UserId": "usr_CydtIC9KUZG0Cbjx",
6 | "Expiry": "2014-10-16T21:52:36.144147885+13:00"
7 | },
8 | "sess_khdIzL8FVrDg9eB1Fip1": {
9 | "Id": "sess_khdIzL8FVrDg9eB1Fip1",
10 | "UserId": "usr_ZRtM7bsqwge7ooxU",
11 | "Expiry": "2014-11-12T22:13:30.730961965+13:00"
12 | },
13 | "sess_rpCFwRBPmdfiP0NJNm4X": {
14 | "Id": "sess_rpCFwRBPmdfiP0NJNm4X",
15 | "UserId": "",
16 | "Expiry": "2014-11-12T21:42:33.717113688+13:00"
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/chapter8/0_base/templates/images/show.html:
--------------------------------------------------------------------------------
1 | {{define "images/show"}}
2 |
3 |
4 |
5 |
6 |
17 |
18 | {{end}}
19 |
--------------------------------------------------------------------------------
/ig/templates/images/show.html:
--------------------------------------------------------------------------------
1 | {{define "images/show"}}
2 |
3 |
4 |
5 |
6 |
17 |
18 | {{end}}
19 |
20 |
--------------------------------------------------------------------------------
/chapter10/0_base/templates/images/show.html:
--------------------------------------------------------------------------------
1 | {{define "images/show"}}
2 |
3 |
4 |
5 |
6 |
17 |
18 | {{end}}
19 |
--------------------------------------------------------------------------------
/chapter6/5_signing_out_and_in/data/sessions.json:
--------------------------------------------------------------------------------
1 | {
2 | "Sessions": {
3 | "sess_5JZPid0vn0m72Q0H3Ghh": {
4 | "Id": "sess_5JZPid0vn0m72Q0H3Ghh",
5 | "UserId": "usr_ZRtM7bsqwge7ooxU",
6 | "Expiry": "2014-11-12T21:42:37.07205867+13:00"
7 | },
8 | "sess_GBEX1Qx0NXmSgXL1nPDg": {
9 | "Id": "sess_GBEX1Qx0NXmSgXL1nPDg",
10 | "UserId": "usr_CydtIC9KUZG0Cbjx",
11 | "Expiry": "2014-10-16T21:52:36.144147885+13:00"
12 | },
13 | "sess_rpCFwRBPmdfiP0NJNm4X": {
14 | "Id": "sess_rpCFwRBPmdfiP0NJNm4X",
15 | "UserId": "",
16 | "Expiry": "2014-11-12T21:42:33.717113688+13:00"
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/chapter9/0_base/templates/images/show.html:
--------------------------------------------------------------------------------
1 | {{define "images/show"}}
2 |
3 |
4 |
5 |
6 |
17 |
18 | {{end}}
19 |
--------------------------------------------------------------------------------
/chapter10/1_pkg_web/templates/images/show.html:
--------------------------------------------------------------------------------
1 | {{define "images/show"}}
2 |
3 |
4 |
5 |
6 |
17 |
18 | {{end}}
19 |
--------------------------------------------------------------------------------
/chapter10/2_godeps/templates/images/show.html:
--------------------------------------------------------------------------------
1 | {{define "images/show"}}
2 |
3 |
4 |
5 |
6 |
17 |
18 | {{end}}
19 |
--------------------------------------------------------------------------------
/chapter7/4_displaying_images/templates/images/show.html:
--------------------------------------------------------------------------------
1 | {{define "images/show"}}
2 |
3 |
4 |
5 |
6 |
17 |
18 | {{end}}
19 |
--------------------------------------------------------------------------------
/chapter8/1_image_resizing/templates/images/show.html:
--------------------------------------------------------------------------------
1 | {{define "images/show"}}
2 |
3 |
4 |
5 |
6 |
17 |
18 | {{end}}
19 |
--------------------------------------------------------------------------------
/chapter8/2_display_resized/templates/images/show.html:
--------------------------------------------------------------------------------
1 | {{define "images/show"}}
2 |
3 |
4 |
5 |
6 |
17 |
18 | {{end}}
19 |
--------------------------------------------------------------------------------
/chapter9/2_mock_interface/templates/images/show.html:
--------------------------------------------------------------------------------
1 | {{define "images/show"}}
2 |
3 |
4 |
5 |
6 |
17 |
18 | {{end}}
19 |
--------------------------------------------------------------------------------
/chapter9/3_http_testing/templates/images/show.html:
--------------------------------------------------------------------------------
1 | {{define "images/show"}}
2 |
3 |
4 |
5 |
6 |
17 |
18 | {{end}}
19 |
--------------------------------------------------------------------------------
/chapter9/4_benchmarking/templates/images/show.html:
--------------------------------------------------------------------------------
1 | {{define "images/show"}}
2 |
3 |
4 |
5 |
6 |
17 |
18 | {{end}}
19 |
--------------------------------------------------------------------------------
/chapter9/1_simple_input_tests/templates/images/show.html:
--------------------------------------------------------------------------------
1 | {{define "images/show"}}
2 |
3 |
4 |
5 |
6 |
17 |
18 | {{end}}
19 |
--------------------------------------------------------------------------------
/chapter3/3-time-handler/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "net/http"
6 | "time"
7 | )
8 |
9 | // UptimeHandler writes the number of seconds since starting to the response.
10 | type UptimeHandler struct {
11 | Started time.Time
12 | }
13 |
14 | func NewUptimeHandler() UptimeHandler {
15 | return UptimeHandler{ Started: time.Now() }
16 | }
17 |
18 | func (h UptimeHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
19 | fmt.Fprintf(
20 | w,
21 | fmt.Sprintf("Current Uptime: %s", time.Since(h.Started)),
22 | )
23 | }
24 |
25 | func main() {
26 | http.Handle("/", NewUptimeHandler())
27 | http.ListenAndServe(":3000", nil)
28 | }
29 |
--------------------------------------------------------------------------------
/chapter3/8-unknown-json-input/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | )
7 |
8 | func FooJSON(input string) {
9 | data := map[string]interface{}{}
10 | err := json.Unmarshal([]byte(input), &data)
11 | if err != nil {
12 | panic(err)
13 | }
14 | foo, _ := data["foo"]
15 | switch foo.(type) {
16 | case float64:
17 | fmt.Printf("Float %f\n", foo)
18 | case string:
19 | fmt.Printf("String %s\n", foo)
20 | default:
21 | fmt.Printf("Something else\n")
22 | }
23 | }
24 | func main() {
25 | FooJSON(`{
26 | "foo": 123
27 | }`)
28 | FooJSON(`{
29 | "foo": "bar"
30 | }`)
31 | FooJSON(`{
32 | "foo": []
33 | }`)
34 | }
35 |
--------------------------------------------------------------------------------
/chapter4/2_first_template/template.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "html/template"
6 | "net/http"
7 | )
8 |
9 | var templates = template.Must(template.New("t").ParseGlob("templates/**/*.html"))
10 |
11 | var errorTemplate = `
12 |
13 |
14 | Error rendering template %s
15 | %s
16 |
17 |
18 | `
19 |
20 | func RenderTemplate(w http.ResponseWriter, request *http.Request, name string, data interface{}) {
21 | err := templates.ExecuteTemplate(w, name, data)
22 | if err != nil {
23 | http.Error(
24 | w,
25 | fmt.Sprintf(errorTemplate, name, err),
26 | http.StatusInternalServerError,
27 | )
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/chapter3/5-html-templates/funcs/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "os"
5 | "text/template"
6 | )
7 |
8 | func Multiply(a, b float64) float64 {
9 | return a * b
10 | }
11 |
12 | func main() {
13 | tmpl := template.New("Foo")
14 | tmpl.Funcs(template.FuncMap{"multiply": Multiply})
15 |
16 | tmpl, err = tmpl.Parse(
17 | "Price: ${{ multiply .Price .Quantity | printf \"%.2f\"}}\n",
18 | )
19 | if err != nil {
20 | panic(err)
21 | }
22 |
23 | type Product struct {
24 | Price float64
25 | Quantity float64
26 | }
27 | err = tmpl.Execute(os.Stdout, Product{
28 | Price: 12.3,
29 | Quantity: 2,
30 | })
31 | if err != nil {
32 | panic(err)
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/chapter5/1_router/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "net/http"
6 |
7 | "github.com/julienschmidt/httprouter"
8 | )
9 |
10 | func main() {
11 | router := NewRouter()
12 |
13 | router.Handle("GET", "/", HandleHome)
14 |
15 | router.ServeFiles(
16 | "/assets/*filepath",
17 | http.Dir("assets/"),
18 | )
19 |
20 | middleware := Middleware{}
21 | middleware.Add(router)
22 | log.Fatal(http.ListenAndServe(":3000", middleware))
23 | }
24 |
25 | // Creates a new router
26 | func NewRouter() *httprouter.Router {
27 | router := httprouter.New()
28 | router.NotFound = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
29 | return router
30 | }
31 |
--------------------------------------------------------------------------------
/chapter6/0_base/errors.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "errors"
4 |
5 | type ValidationError error
6 |
7 | var (
8 | errNoUsername = ValidationError(errors.New("You must supply a username"))
9 | errNoEmail = ValidationError(errors.New("You must supply an email"))
10 | errNoPassword = ValidationError(errors.New("You must supply a password"))
11 | errPasswordTooShort = ValidationError(errors.New("Your password is too short"))
12 | errUsernameExists = ValidationError(errors.New("That username is taken"))
13 | errEmailExists = ValidationError(errors.New("That email address has an account"))
14 | )
15 |
16 | func IsValidationError(err error) bool {
17 | _, ok := err.(ValidationError)
18 | return ok
19 | }
20 |
--------------------------------------------------------------------------------
/chapter5/3_user_store/errors.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "errors"
4 |
5 | type ValidationError error
6 |
7 | var (
8 | errNoUsername = ValidationError(errors.New("You must supply a username"))
9 | errNoEmail = ValidationError(errors.New("You must supply an email"))
10 | errNoPassword = ValidationError(errors.New("You must supply a password"))
11 | errPasswordTooShort = ValidationError(errors.New("Your password is too short"))
12 | errUsernameExists = ValidationError(errors.New("That username is taken"))
13 | errEmailExists = ValidationError(errors.New("That email address has an account"))
14 | )
15 |
16 | func IsValidationError(err error) bool {
17 | _, ok := err.(ValidationError)
18 | return ok
19 | }
20 |
--------------------------------------------------------------------------------
/chapter6/1_new_session/errors.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "errors"
4 |
5 | type ValidationError error
6 |
7 | var (
8 | errNoUsername = ValidationError(errors.New("You must supply a username"))
9 | errNoEmail = ValidationError(errors.New("You must supply an email"))
10 | errNoPassword = ValidationError(errors.New("You must supply a password"))
11 | errPasswordTooShort = ValidationError(errors.New("Your password is too short"))
12 | errUsernameExists = ValidationError(errors.New("That username is taken"))
13 | errEmailExists = ValidationError(errors.New("That email address has an account"))
14 | )
15 |
16 | func IsValidationError(err error) bool {
17 | _, ok := err.(ValidationError)
18 | return ok
19 | }
20 |
--------------------------------------------------------------------------------
/chapter6/2_session_store/errors.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "errors"
4 |
5 | type ValidationError error
6 |
7 | var (
8 | errNoUsername = ValidationError(errors.New("You must supply a username"))
9 | errNoEmail = ValidationError(errors.New("You must supply an email"))
10 | errNoPassword = ValidationError(errors.New("You must supply a password"))
11 | errPasswordTooShort = ValidationError(errors.New("Your password is too short"))
12 | errUsernameExists = ValidationError(errors.New("That username is taken"))
13 | errEmailExists = ValidationError(errors.New("That email address has an account"))
14 | )
15 |
16 | func IsValidationError(err error) bool {
17 | _, ok := err.(ValidationError)
18 | return ok
19 | }
20 |
--------------------------------------------------------------------------------
/chapter6/3_require_login/errors.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "errors"
4 |
5 | type ValidationError error
6 |
7 | var (
8 | errNoUsername = ValidationError(errors.New("You must supply a username"))
9 | errNoEmail = ValidationError(errors.New("You must supply an email"))
10 | errNoPassword = ValidationError(errors.New("You must supply a password"))
11 | errPasswordTooShort = ValidationError(errors.New("Your password is too short"))
12 | errUsernameExists = ValidationError(errors.New("That username is taken"))
13 | errEmailExists = ValidationError(errors.New("That email address has an account"))
14 | )
15 |
16 | func IsValidationError(err error) bool {
17 | _, ok := err.(ValidationError)
18 | return ok
19 | }
20 |
--------------------------------------------------------------------------------
/chapter6/4_template_data/errors.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "errors"
4 |
5 | type ValidationError error
6 |
7 | var (
8 | errNoUsername = ValidationError(errors.New("You must supply a username"))
9 | errNoEmail = ValidationError(errors.New("You must supply an email"))
10 | errNoPassword = ValidationError(errors.New("You must supply a password"))
11 | errPasswordTooShort = ValidationError(errors.New("Your password is too short"))
12 | errUsernameExists = ValidationError(errors.New("That username is taken"))
13 | errEmailExists = ValidationError(errors.New("That email address has an account"))
14 | )
15 |
16 | func IsValidationError(err error) bool {
17 | _, ok := err.(ValidationError)
18 | return ok
19 | }
20 |
--------------------------------------------------------------------------------
/chapter10/2_godeps/Godeps/_workspace/src/github.com/go-sql-driver/mysql/result.go:
--------------------------------------------------------------------------------
1 | // Go MySQL Driver - A MySQL-Driver for Go's database/sql package
2 | //
3 | // Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
4 | //
5 | // This Source Code Form is subject to the terms of the Mozilla Public
6 | // License, v. 2.0. If a copy of the MPL was not distributed with this file,
7 | // You can obtain one at http://mozilla.org/MPL/2.0/.
8 |
9 | package mysql
10 |
11 | type mysqlResult struct {
12 | affectedRows int64
13 | insertId int64
14 | }
15 |
16 | func (res *mysqlResult) LastInsertId() (int64, error) {
17 | return res.insertId, nil
18 | }
19 |
20 | func (res *mysqlResult) RowsAffected() (int64, error) {
21 | return res.affectedRows, nil
22 | }
23 |
--------------------------------------------------------------------------------
/chapter6/0_base/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "net/http"
6 |
7 | "github.com/julienschmidt/httprouter"
8 | )
9 |
10 | func main() {
11 | router := NewRouter()
12 |
13 | router.Handle("GET", "/", HandleHome)
14 | router.Handle("GET", "/register", HandleUserNew)
15 | router.Handle("POST", "/register", HandleUserCreate)
16 |
17 | router.ServeFiles(
18 | "/assets/*filepath",
19 | http.Dir("assets/"),
20 | )
21 |
22 | middleware := Middleware{}
23 | middleware.Add(router)
24 | log.Fatal(http.ListenAndServe(":3000", middleware))
25 | }
26 |
27 | // Creates a new router
28 | func NewRouter() *httprouter.Router {
29 | router := httprouter.New()
30 | router.NotFound = func(http.ResponseWriter, *http.Request) {}
31 | return router
32 | }
33 |
--------------------------------------------------------------------------------
/chapter5/2_registration/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "net/http"
6 |
7 | "github.com/julienschmidt/httprouter"
8 | )
9 |
10 | func main() {
11 | router := NewRouter()
12 |
13 | router.Handle("GET", "/", HandleHome)
14 | router.Handle("GET", "/register", HandleUserNew)
15 | router.Handle("POST", "/register", HandleUserCreate)
16 |
17 | router.ServeFiles(
18 | "/assets/*filepath",
19 | http.Dir("assets/"),
20 | )
21 |
22 | middleware := Middleware{}
23 | middleware.Add(router)
24 | log.Fatal(http.ListenAndServe(":3000", middleware))
25 | }
26 |
27 | // Creates a new router
28 | func NewRouter() *httprouter.Router {
29 | router := httprouter.New()
30 | router.NotFound = func(http.ResponseWriter, *http.Request) {}
31 | return router
32 | }
33 |
--------------------------------------------------------------------------------
/chapter5/3_user_store/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "net/http"
6 |
7 | "github.com/julienschmidt/httprouter"
8 | )
9 |
10 | func main() {
11 | router := NewRouter()
12 |
13 | router.Handle("GET", "/", HandleHome)
14 | router.Handle("GET", "/register", HandleUserNew)
15 | router.Handle("POST", "/register", HandleUserCreate)
16 |
17 | router.ServeFiles(
18 | "/assets/*filepath",
19 | http.Dir("assets/"),
20 | )
21 |
22 | middleware := Middleware{}
23 | middleware.Add(router)
24 | log.Fatal(http.ListenAndServe(":3000", middleware))
25 | }
26 |
27 | // Creates a new router
28 | func NewRouter() *httprouter.Router {
29 | router := httprouter.New()
30 | router.NotFound = func(http.ResponseWriter, *http.Request) {}
31 | return router
32 | }
33 |
--------------------------------------------------------------------------------
/chapter6/1_new_session/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "net/http"
6 |
7 | "github.com/julienschmidt/httprouter"
8 | )
9 |
10 | func main() {
11 | router := NewRouter()
12 |
13 | router.Handle("GET", "/", HandleHome)
14 | router.Handle("GET", "/register", HandleUserNew)
15 | router.Handle("POST", "/register", HandleUserCreate)
16 |
17 | router.ServeFiles(
18 | "/assets/*filepath",
19 | http.Dir("assets/"),
20 | )
21 |
22 | middleware := Middleware{}
23 | middleware.Add(router)
24 | log.Fatal(http.ListenAndServe(":3000", middleware))
25 | }
26 |
27 | // Creates a new router
28 | func NewRouter() *httprouter.Router {
29 | router := httprouter.New()
30 | router.NotFound = func(http.ResponseWriter, *http.Request) {}
31 | return router
32 | }
33 |
--------------------------------------------------------------------------------
/chapter6/2_session_store/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "net/http"
6 |
7 | "github.com/julienschmidt/httprouter"
8 | )
9 |
10 | func main() {
11 | router := NewRouter()
12 |
13 | router.Handle("GET", "/", HandleHome)
14 | router.Handle("GET", "/register", HandleUserNew)
15 | router.Handle("POST", "/register", HandleUserCreate)
16 |
17 | router.ServeFiles(
18 | "/assets/*filepath",
19 | http.Dir("assets/"),
20 | )
21 |
22 | middleware := Middleware{}
23 | middleware.Add(router)
24 | log.Fatal(http.ListenAndServe(":3000", middleware))
25 | }
26 |
27 | // Creates a new router
28 | func NewRouter() *httprouter.Router {
29 | router := httprouter.New()
30 | router.NotFound = func(http.ResponseWriter, *http.Request) {}
31 | return router
32 | }
33 |
--------------------------------------------------------------------------------
/chapter6/3_require_login/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "net/http"
6 |
7 | "github.com/julienschmidt/httprouter"
8 | )
9 |
10 | func main() {
11 | router := NewRouter()
12 |
13 | router.Handle("GET", "/", HandleHome)
14 | router.Handle("GET", "/register", HandleUserNew)
15 | router.Handle("POST", "/register", HandleUserCreate)
16 |
17 | router.ServeFiles(
18 | "/assets/*filepath",
19 | http.Dir("assets/"),
20 | )
21 |
22 | middleware := Middleware{}
23 | middleware.Add(router)
24 | log.Fatal(http.ListenAndServe(":3000", middleware))
25 | }
26 |
27 | // Creates a new router
28 | func NewRouter() *httprouter.Router {
29 | router := httprouter.New()
30 | router.NotFound = func(http.ResponseWriter, *http.Request) {}
31 | return router
32 | }
33 |
--------------------------------------------------------------------------------
/chapter6/4_template_data/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "net/http"
6 |
7 | "github.com/julienschmidt/httprouter"
8 | )
9 |
10 | func main() {
11 | router := NewRouter()
12 |
13 | router.Handle("GET", "/", HandleHome)
14 | router.Handle("GET", "/register", HandleUserNew)
15 | router.Handle("POST", "/register", HandleUserCreate)
16 |
17 | router.ServeFiles(
18 | "/assets/*filepath",
19 | http.Dir("assets/"),
20 | )
21 |
22 | middleware := Middleware{}
23 | middleware.Add(router)
24 | log.Fatal(http.ListenAndServe(":3000", middleware))
25 | }
26 |
27 | // Creates a new router
28 | func NewRouter() *httprouter.Router {
29 | router := httprouter.New()
30 | router.NotFound = func(http.ResponseWriter, *http.Request) {}
31 | return router
32 | }
33 |
--------------------------------------------------------------------------------
/chapter6/1_new_session/session.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 | "time"
6 | )
7 |
8 | type Session struct {
9 | ID string
10 | UserID string
11 | Expiry time.Time
12 | }
13 |
14 | const (
15 | // Keep users logged in for 3 days
16 | sessionLength = 24 * 3 * time.Hour
17 | sessionCookieName = "GophrSession"
18 | sessionIDLength = 20
19 | )
20 |
21 | func NewSession(w http.ResponseWriter) *Session {
22 | expiry := time.Now().Add(sessionLength)
23 |
24 | session := &Session{
25 | ID: GenerateID("sess", sessionIDLength),
26 | Expiry: expiry,
27 | }
28 |
29 | cookie := http.Cookie{
30 | Name: sessionCookieName,
31 | Value: session.ID,
32 | Expires: session.Expiry,
33 | }
34 |
35 | http.SetCookie(w, &cookie)
36 | return session
37 | }
38 |
--------------------------------------------------------------------------------
/chapter6/2_session_store/session.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 | "time"
6 | )
7 |
8 | type Session struct {
9 | ID string
10 | UserID string
11 | Expiry time.Time
12 | }
13 |
14 | const (
15 | // Keep users logged in for 3 days
16 | sessionLength = 24 * 3 * time.Hour
17 | sessionCookieName = "GophrSession"
18 | sessionIDLength = 20
19 | )
20 |
21 | func NewSession(w http.ResponseWriter) *Session {
22 | expiry := time.Now().Add(sessionLength)
23 |
24 | session := &Session{
25 | ID: GenerateID("sess", sessionIDLength),
26 | Expiry: expiry,
27 | }
28 |
29 | cookie := http.Cookie{
30 | Name: sessionCookieName,
31 | Value: session.ID,
32 | Expires: session.Expiry,
33 | }
34 |
35 | http.SetCookie(w, &cookie)
36 | return session
37 | }
38 |
--------------------------------------------------------------------------------
/chapter5/2_registration/handle_user.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleUserNew(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
10 | RenderTemplate(w, r, "users/new", nil)
11 | }
12 |
13 | func HandleUserCreate(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
14 | user, err := NewUser(
15 | r.FormValue("username"),
16 | r.FormValue("email"),
17 | r.FormValue("password"),
18 | )
19 |
20 | if err != nil {
21 | if IsValidationError(err) {
22 | RenderTemplate(w, r, "users/new", map[string]interface{}{
23 | "Error": err.Error(),
24 | "User": user,
25 | })
26 | return
27 | }
28 | panic(err)
29 | }
30 |
31 | http.Redirect(w, r, "/?flash=User+created", http.StatusFound)
32 | }
33 |
--------------------------------------------------------------------------------
/ig/templates/sessions/new.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/new"}}
2 |
3 |
4 |
Sign In
5 | {{if .Error}}
6 |
7 | {{.Error}}
8 |
9 | {{end}}
10 |
22 |
23 |
24 | {{end}}
25 |
--------------------------------------------------------------------------------
/chapter10/0_base/templates/sessions/new.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/new"}}
2 |
3 |
4 |
Sign In
5 | {{if .Error}}
6 |
7 | {{.Error}}
8 |
9 | {{end}}
10 |
22 |
23 |
24 | {{end}}
25 |
--------------------------------------------------------------------------------
/chapter7/0_base/templates/sessions/new.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/new"}}
2 |
3 |
4 |
Sign In
5 | {{if .Error}}
6 |
7 | {{.Error}}
8 |
9 | {{end}}
10 |
22 |
23 |
24 | {{end}}
25 |
--------------------------------------------------------------------------------
/chapter7/1_mysql/templates/sessions/new.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/new"}}
2 |
3 |
4 |
Sign In
5 | {{if .Error}}
6 |
7 | {{.Error}}
8 |
9 | {{end}}
10 |
22 |
23 |
24 | {{end}}
25 |
--------------------------------------------------------------------------------
/chapter8/0_base/templates/sessions/new.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/new"}}
2 |
3 |
4 |
Sign In
5 | {{if .Error}}
6 |
7 | {{.Error}}
8 |
9 | {{end}}
10 |
22 |
23 |
24 | {{end}}
25 |
--------------------------------------------------------------------------------
/chapter9/0_base/templates/sessions/new.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/new"}}
2 |
3 |
4 |
Sign In
5 | {{if .Error}}
6 |
7 | {{.Error}}
8 |
9 | {{end}}
10 |
22 |
23 |
24 | {{end}}
25 |
--------------------------------------------------------------------------------
/ig/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter10/1_pkg_web/templates/sessions/new.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/new"}}
2 |
3 |
4 |
Sign In
5 | {{if .Error}}
6 |
7 | {{.Error}}
8 |
9 | {{end}}
10 |
22 |
23 |
24 | {{end}}
25 |
--------------------------------------------------------------------------------
/chapter10/2_godeps/templates/sessions/new.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/new"}}
2 |
3 |
4 |
Sign In
5 | {{if .Error}}
6 |
7 | {{.Error}}
8 |
9 | {{end}}
10 |
22 |
23 |
24 | {{end}}
25 |
--------------------------------------------------------------------------------
/chapter3/7-unmarshaling-json/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "io/ioutil"
7 | )
8 |
9 | func main() {
10 | type Config struct {
11 | Name string `json:"SiteName"`
12 | URL string `json:"SiteUrl"`
13 | Database struct {
14 | Name string
15 | Host string
16 | Port int
17 | Username string
18 | Password string
19 | }
20 | }
21 | conf := Config{}
22 | data, err := ioutil.ReadFile("config.json")
23 | if err != nil {
24 | panic(err)
25 | }
26 | err = json.Unmarshal(data, &conf)
27 | if err != nil {
28 | panic(err)
29 | }
30 | fmt.Printf("Site: %s (%s)\n", conf.Name, conf.URL)
31 | db := conf.Database
32 | fmt.Printf(
33 | "DB: mysql://%s:%s@%s:%d/%s\n",
34 | db.Username,
35 | db.Password,
36 | db.Host,
37 | db.Port,
38 | db.Name,
39 | )
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/chapter6/6_edit_user/templates/sessions/new.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/new"}}
2 |
3 |
4 |
Sign In
5 | {{if .Error}}
6 |
7 | {{.Error}}
8 |
9 | {{end}}
10 |
22 |
23 |
24 | {{end}}
25 |
--------------------------------------------------------------------------------
/chapter10/0_base/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter6/0_base/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter7/0_base/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter7/1_mysql/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter7/2_db_image_store/templates/sessions/new.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/new"}}
2 |
3 |
4 |
Sign In
5 | {{if .Error}}
6 |
7 | {{.Error}}
8 |
9 | {{end}}
10 |
22 |
23 |
24 | {{end}}
25 |
--------------------------------------------------------------------------------
/chapter7/3_uploading_images/templates/sessions/new.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/new"}}
2 |
3 |
4 |
Sign In
5 | {{if .Error}}
6 |
7 | {{.Error}}
8 |
9 | {{end}}
10 |
22 |
23 |
24 | {{end}}
25 |
--------------------------------------------------------------------------------
/chapter8/0_base/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter8/1_image_resizing/templates/sessions/new.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/new"}}
2 |
3 |
4 |
Sign In
5 | {{if .Error}}
6 |
7 | {{.Error}}
8 |
9 | {{end}}
10 |
22 |
23 |
24 | {{end}}
25 |
--------------------------------------------------------------------------------
/chapter8/2_display_resized/templates/sessions/new.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/new"}}
2 |
3 |
4 |
Sign In
5 | {{if .Error}}
6 |
7 | {{.Error}}
8 |
9 | {{end}}
10 |
22 |
23 |
24 | {{end}}
25 |
--------------------------------------------------------------------------------
/chapter9/0_base/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter9/2_mock_interface/templates/sessions/new.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/new"}}
2 |
3 |
4 |
Sign In
5 | {{if .Error}}
6 |
7 | {{.Error}}
8 |
9 | {{end}}
10 |
22 |
23 |
24 | {{end}}
25 |
--------------------------------------------------------------------------------
/chapter9/3_http_testing/templates/sessions/new.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/new"}}
2 |
3 |
4 |
Sign In
5 | {{if .Error}}
6 |
7 | {{.Error}}
8 |
9 | {{end}}
10 |
22 |
23 |
24 | {{end}}
25 |
--------------------------------------------------------------------------------
/chapter9/4_benchmarking/templates/sessions/new.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/new"}}
2 |
3 |
4 |
Sign In
5 | {{if .Error}}
6 |
7 | {{.Error}}
8 |
9 | {{end}}
10 |
22 |
23 |
24 | {{end}}
25 |
--------------------------------------------------------------------------------
/chapter10/1_pkg_web/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter10/2_godeps/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter5/3_user_store/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter6/5_signing_out_and_in/templates/sessions/new.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/new"}}
2 |
3 |
4 |
Sign In
5 | {{if .Error}}
6 |
7 | {{.Error}}
8 |
9 | {{end}}
10 |
22 |
23 |
24 | {{end}}
25 |
--------------------------------------------------------------------------------
/chapter6/6_edit_user/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter7/4_displaying_images/templates/sessions/new.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/new"}}
2 |
3 |
4 |
Sign In
5 | {{if .Error}}
6 |
7 | {{.Error}}
8 |
9 | {{end}}
10 |
22 |
23 |
24 | {{end}}
25 |
--------------------------------------------------------------------------------
/chapter9/1_simple_input_tests/templates/sessions/new.html:
--------------------------------------------------------------------------------
1 | {{define "sessions/new"}}
2 |
3 |
4 |
Sign In
5 | {{if .Error}}
6 |
7 | {{.Error}}
8 |
9 | {{end}}
10 |
22 |
23 |
24 | {{end}}
25 |
--------------------------------------------------------------------------------
/chapter5/2_registration/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter6/1_new_session/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter6/2_session_store/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter6/3_require_login/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter6/4_template_data/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter7/2_db_image_store/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter8/1_image_resizing/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter8/2_display_resized/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter9/2_mock_interface/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter9/3_http_testing/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter9/4_benchmarking/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter6/5_signing_out_and_in/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter7/3_uploading_images/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter7/4_displaying_images/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter9/1_simple_input_tests/id.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/rand"
5 | "fmt"
6 | )
7 |
8 | // Source String used when generating a random identifier.
9 | const idSource = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 |
11 | // Save the length in a constant so we don't look it up each time.
12 | const idSourceLen = byte(len(idSource))
13 |
14 | // GenerateID creates a prefixed random identifier.
15 | func GenerateID(prefix string, length int) string {
16 | // Create an array with the correct capacity
17 | id := make([]byte, length)
18 | // Fill our array with random numbers
19 | rand.Read(id)
20 |
21 | // Replace each random number with an alphanumeric value
22 | for i, b := range id {
23 | id[i] = idSource[b%idSourceLen]
24 | }
25 |
26 | // Return the formatted id
27 | return fmt.Sprintf("%s_%s", prefix, string(id))
28 | }
29 |
--------------------------------------------------------------------------------
/chapter6/5_signing_out_and_in/errors.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "errors"
4 |
5 | type ValidationError error
6 |
7 | var (
8 | errNoUsername = ValidationError(errors.New("You must supply a username"))
9 | errNoEmail = ValidationError(errors.New("You must supply an email"))
10 | errNoPassword = ValidationError(errors.New("You must supply a password"))
11 | errPasswordTooShort = ValidationError(errors.New("Your password is too short"))
12 | errUsernameExists = ValidationError(errors.New("That username is taken"))
13 | errEmailExists = ValidationError(errors.New("That email address has an account"))
14 | errCredentialsIncorrect = ValidationError(errors.New("We couldn’t find a user with the supplied username and password combination"))
15 | )
16 |
17 | func IsValidationError(err error) bool {
18 | _, ok := err.(ValidationError)
19 | return ok
20 | }
21 |
--------------------------------------------------------------------------------
/chapter10/0_base/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter6/0_base/handle_user.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleUserNew(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
10 | RenderTemplate(w, r, "users/new", nil)
11 | }
12 |
13 | func HandleUserCreate(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
14 | user, err := NewUser(
15 | r.FormValue("username"),
16 | r.FormValue("email"),
17 | r.FormValue("password"),
18 | )
19 |
20 | if err != nil {
21 | if IsValidationError(err) {
22 | RenderTemplate(w, r, "users/new", map[string]interface{}{
23 | "Error": err.Error(),
24 | "User": user,
25 | })
26 | return
27 | }
28 | panic(err)
29 | return
30 | }
31 |
32 | err = globalUserStore.Save(user)
33 | if err != nil {
34 | panic(err)
35 | return
36 | }
37 |
38 | http.Redirect(w, r, "/?flash=User+created", http.StatusFound)
39 | }
40 |
--------------------------------------------------------------------------------
/chapter6/0_base/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter7/0_base/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter7/1_mysql/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter8/0_base/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter9/0_base/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter10/1_pkg_web/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter10/2_godeps/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter5/3_user_store/handle_user.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/julienschmidt/httprouter"
7 | )
8 |
9 | func HandleUserNew(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
10 | RenderTemplate(w, r, "users/new", nil)
11 | }
12 |
13 | func HandleUserCreate(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
14 | user, err := NewUser(
15 | r.FormValue("username"),
16 | r.FormValue("email"),
17 | r.FormValue("password"),
18 | )
19 |
20 | if err != nil {
21 | if IsValidationError(err) {
22 | RenderTemplate(w, r, "users/new", map[string]interface{}{
23 | "Error": err.Error(),
24 | "User": user,
25 | })
26 | return
27 | }
28 | panic(err)
29 | return
30 | }
31 |
32 | err = globalUserStore.Save(user)
33 | if err != nil {
34 | panic(err)
35 | return
36 | }
37 |
38 | http.Redirect(w, r, "/?flash=User+created", http.StatusFound)
39 | }
40 |
--------------------------------------------------------------------------------
/chapter5/3_user_store/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter6/1_new_session/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter6/6_edit_user/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter10/2_godeps/Godeps/_workspace/src/github.com/go-sql-driver/mysql/transaction.go:
--------------------------------------------------------------------------------
1 | // Go MySQL Driver - A MySQL-Driver for Go's database/sql package
2 | //
3 | // Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
4 | //
5 | // This Source Code Form is subject to the terms of the Mozilla Public
6 | // License, v. 2.0. If a copy of the MPL was not distributed with this file,
7 | // You can obtain one at http://mozilla.org/MPL/2.0/.
8 |
9 | package mysql
10 |
11 | type mysqlTx struct {
12 | mc *mysqlConn
13 | }
14 |
15 | func (tx *mysqlTx) Commit() (err error) {
16 | if tx.mc == nil || tx.mc.netConn == nil {
17 | return ErrInvalidConn
18 | }
19 | err = tx.mc.exec("COMMIT")
20 | tx.mc = nil
21 | return
22 | }
23 |
24 | func (tx *mysqlTx) Rollback() (err error) {
25 | if tx.mc == nil || tx.mc.netConn == nil {
26 | return ErrInvalidConn
27 | }
28 | err = tx.mc.exec("ROLLBACK")
29 | tx.mc = nil
30 | return
31 | }
32 |
--------------------------------------------------------------------------------
/chapter5/2_registration/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter6/2_session_store/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter6/3_require_login/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter6/4_template_data/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter7/2_db_image_store/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter7/3_uploading_images/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter8/1_image_resizing/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter8/2_display_resized/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter9/2_mock_interface/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter9/3_http_testing/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter9/4_benchmarking/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter6/5_signing_out_and_in/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter7/4_displaying_images/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/chapter9/1_simple_input_tests/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
Sign Up
4 | {{if .Error}}
5 |
6 | {{.Error}}
7 |
8 | {{end}}
9 |
24 |
25 | {{end}}
26 |
--------------------------------------------------------------------------------
/ig/templates/users/new.html:
--------------------------------------------------------------------------------
1 | {{define "users/new"}}
2 |
3 |
4 |
Sign Up
5 | {{if .Error}}
6 |
7 | {{.Error}}
8 |
9 | {{end}}
10 |
25 |
26 |
27 | {{end}}
28 |
--------------------------------------------------------------------------------
/chapter7/0_base/errors.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "errors"
4 |
5 | type ValidationError error
6 |
7 | var (
8 | errNoUsername = ValidationError(errors.New("You must supply a username"))
9 | errNoEmail = ValidationError(errors.New("You must supply an email"))
10 | errNoPassword = ValidationError(errors.New("You must supply a password"))
11 | errPasswordTooShort = ValidationError(errors.New("Your password is too short"))
12 | errPasswordIncorrect = ValidationError(errors.New("Password did not match"))
13 | errUsernameExists = ValidationError(errors.New("That username is taken"))
14 | errEmailExists = ValidationError(errors.New("That email address has an account"))
15 | errCredentialsIncorrect = ValidationError(errors.New("We couldn’t find a user with the supplied username and password combination"))
16 | )
17 |
18 | func IsValidationError(err error) bool {
19 | _, ok := err.(ValidationError)
20 | return ok
21 | }
22 |
--------------------------------------------------------------------------------
/chapter7/1_mysql/errors.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "errors"
4 |
5 | type ValidationError error
6 |
7 | var (
8 | errNoUsername = ValidationError(errors.New("You must supply a username"))
9 | errNoEmail = ValidationError(errors.New("You must supply an email"))
10 | errNoPassword = ValidationError(errors.New("You must supply a password"))
11 | errPasswordTooShort = ValidationError(errors.New("Your password is too short"))
12 | errPasswordIncorrect = ValidationError(errors.New("Password did not match"))
13 | errUsernameExists = ValidationError(errors.New("That username is taken"))
14 | errEmailExists = ValidationError(errors.New("That email address has an account"))
15 | errCredentialsIncorrect = ValidationError(errors.New("We couldn’t find a user with the supplied username and password combination"))
16 | )
17 |
18 | func IsValidationError(err error) bool {
19 | _, ok := err.(ValidationError)
20 | return ok
21 | }
22 |
--------------------------------------------------------------------------------
/chapter6/6_edit_user/errors.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "errors"
4 |
5 | type ValidationError error
6 |
7 | var (
8 | errNoUsername = ValidationError(errors.New("You must supply a username"))
9 | errNoEmail = ValidationError(errors.New("You must supply an email"))
10 | errNoPassword = ValidationError(errors.New("You must supply a password"))
11 | errPasswordTooShort = ValidationError(errors.New("Your password is too short"))
12 | errPasswordIncorrect = ValidationError(errors.New("Password did not match"))
13 | errUsernameExists = ValidationError(errors.New("That username is taken"))
14 | errEmailExists = ValidationError(errors.New("That email address has an account"))
15 | errCredentialsIncorrect = ValidationError(errors.New("We couldn’t find a user with the supplied username and password combination"))
16 | )
17 |
18 | func IsValidationError(err error) bool {
19 | _, ok := err.(ValidationError)
20 | return ok
21 | }
22 |
--------------------------------------------------------------------------------
/chapter7/0_base/templates/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
23 |
24 |
25 | {{if .Flash}}
26 |
27 | {{.Flash}}
28 |
29 | {{end}}
30 | {{ yield }}
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/chapter10/2_godeps/Godeps/_workspace/src/golang.org/x/image/tiff/buffer_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package tiff
6 |
7 | import (
8 | "io"
9 | "strings"
10 | "testing"
11 | )
12 |
13 | var readAtTests = []struct {
14 | n int
15 | off int64
16 | s string
17 | err error
18 | }{
19 | {2, 0, "ab", nil},
20 | {6, 0, "abcdef", nil},
21 | {3, 3, "def", nil},
22 | {3, 5, "f", io.EOF},
23 | {3, 6, "", io.EOF},
24 | }
25 |
26 | func TestReadAt(t *testing.T) {
27 | r := newReaderAt(strings.NewReader("abcdef"))
28 | b := make([]byte, 10)
29 | for _, test := range readAtTests {
30 | n, err := r.ReadAt(b[:test.n], test.off)
31 | s := string(b[:n])
32 | if s != test.s || err != test.err {
33 | t.Errorf("buffer.ReadAt(<%v bytes>, %v): got %v, %q; want %v, %q", test.n, test.off, err, s, test.err, test.s)
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/chapter6/6_edit_user/templates/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
23 |
24 |
25 | {{if .Flash}}
26 |
27 | {{.Flash}}
28 |
29 | {{end}}
30 | {{ yield }}
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/chapter7/1_mysql/templates/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
23 |
24 |
25 | {{if .Flash}}
26 |
27 | {{.Flash}}
28 |
29 | {{end}}
30 | {{ yield }}
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/chapter7/2_db_image_store/errors.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "errors"
4 |
5 | type ValidationError error
6 |
7 | var (
8 | errNoUsername = ValidationError(errors.New("You must supply a username"))
9 | errNoEmail = ValidationError(errors.New("You must supply an email"))
10 | errNoPassword = ValidationError(errors.New("You must supply a password"))
11 | errPasswordTooShort = ValidationError(errors.New("Your password is too short"))
12 | errPasswordIncorrect = ValidationError(errors.New("Password did not match"))
13 | errUsernameExists = ValidationError(errors.New("That username is taken"))
14 | errEmailExists = ValidationError(errors.New("That email address has an account"))
15 | errCredentialsIncorrect = ValidationError(errors.New("We couldn’t find a user with the supplied username and password combination"))
16 | )
17 |
18 | func IsValidationError(err error) bool {
19 | _, ok := err.(ValidationError)
20 | return ok
21 | }
22 |
--------------------------------------------------------------------------------
/chapter6/4_template_data/templates/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
23 |
24 |
25 | {{if .Flash}}
26 |
27 | {{.Flash}}
28 |
29 | {{end}}
30 | {{ yield }}
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/chapter7/2_db_image_store/templates/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
23 |
24 |
25 | {{if .Flash}}
26 |
27 | {{.Flash}}
28 |
29 | {{end}}
30 | {{ yield }}
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/chapter6/5_signing_out_and_in/templates/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
23 |
24 |
25 | {{if .Flash}}
26 |
27 | {{.Flash}}
28 |
29 | {{end}}
30 | {{ yield }}
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/chapter10/0_base/image_test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 | "net/http/httptest"
6 | "testing"
7 | )
8 |
9 | func TestImageCreateFromURLInvalidStatusCode(t *testing.T) {
10 | server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
11 | w.WriteHeader(404)
12 | }))
13 | defer server.Close()
14 |
15 | image := Image{}
16 | err := image.CreateFromURL(server.URL)
17 | if err != errImageURLInvalid {
18 | t.Errorf("Expected errImageURLInvalid but got %s", err)
19 | }
20 | }
21 |
22 | func TestImageCreateFromURLInvalidContentType(t *testing.T) {
23 | server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
24 | w.WriteHeader(200)
25 | w.Header().Add("Content-Type", "text/html")
26 | }))
27 | defer server.Close()
28 |
29 | image := Image{}
30 | err := image.CreateFromURL(server.URL)
31 | if err != errInvalidImageType {
32 | t.Errorf("Expected errInvalidImageType but got %s", err)
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/chapter10/1_pkg_web/image_test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 | "net/http/httptest"
6 | "testing"
7 | )
8 |
9 | func TestImageCreateFromURLInvalidStatusCode(t *testing.T) {
10 | server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
11 | w.WriteHeader(404)
12 | }))
13 | defer server.Close()
14 |
15 | image := Image{}
16 | err := image.CreateFromURL(server.URL)
17 | if err != errImageURLInvalid {
18 | t.Errorf("Expected errImageURLInvalid but got %s", err)
19 | }
20 | }
21 |
22 | func TestImageCreateFromURLInvalidContentType(t *testing.T) {
23 | server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
24 | w.WriteHeader(200)
25 | w.Header().Add("Content-Type", "text/html")
26 | }))
27 | defer server.Close()
28 |
29 | image := Image{}
30 | err := image.CreateFromURL(server.URL)
31 | if err != errInvalidImageType {
32 | t.Errorf("Expected errInvalidImageType but got %s", err)
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/chapter10/2_godeps/image_test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 | "net/http/httptest"
6 | "testing"
7 | )
8 |
9 | func TestImageCreateFromURLInvalidStatusCode(t *testing.T) {
10 | server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
11 | w.WriteHeader(404)
12 | }))
13 | defer server.Close()
14 |
15 | image := Image{}
16 | err := image.CreateFromURL(server.URL)
17 | if err != errImageURLInvalid {
18 | t.Errorf("Expected errImageURLInvalid but got %s", err)
19 | }
20 | }
21 |
22 | func TestImageCreateFromURLInvalidContentType(t *testing.T) {
23 | server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
24 | w.WriteHeader(200)
25 | w.Header().Add("Content-Type", "text/html")
26 | }))
27 | defer server.Close()
28 |
29 | image := Image{}
30 | err := image.CreateFromURL(server.URL)
31 | if err != errInvalidImageType {
32 | t.Errorf("Expected errInvalidImageType but got %s", err)
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/chapter5/2_registration/user.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "code.google.com/p/go.crypto/bcrypt"
4 |
5 | type User struct {
6 | ID string
7 | Email string
8 | HashedPassword string
9 | Username string
10 | }
11 |
12 | const (
13 | hashCost = 10
14 | passwordLength = 6
15 | userIDLength = 16
16 | )
17 |
18 | func NewUser(username, email, password string) (User, error) {
19 | user := User{
20 | Email: email,
21 | Username: username,
22 | }
23 | if username == "" {
24 | return user, errNoUsername
25 | }
26 |
27 | if email == "" {
28 | return user, errNoEmail
29 | }
30 |
31 | if password == "" {
32 | return user, errNoPassword
33 | }
34 |
35 | if len(password) < passwordLength {
36 | return user, errPasswordTooShort
37 | }
38 | hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), hashCost)
39 |
40 | user.HashedPassword = string(hashedPassword)
41 | user.ID = GenerateID("usr", userIDLength)
42 | return user, err
43 | }
44 |
--------------------------------------------------------------------------------
/chapter9/3_http_testing/image_test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 | "net/http/httptest"
6 | "testing"
7 | )
8 |
9 | func TestImageCreateFromURLInvalidStatusCode(t *testing.T) {
10 | server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
11 | w.WriteHeader(404)
12 | }))
13 | defer server.Close()
14 |
15 | image := Image{}
16 | err := image.CreateFromURL(server.URL)
17 | if err != errImageURLInvalid {
18 | t.Errorf("Expected errImageURLInvalid but got %s", err)
19 | }
20 | }
21 |
22 | func TestImageCreateFromURLInvalidContentType(t *testing.T) {
23 | server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
24 | w.WriteHeader(200)
25 | w.Header().Add("Content-Type", "text/html")
26 | }))
27 | defer server.Close()
28 |
29 | image := Image{}
30 | err := image.CreateFromURL(server.URL)
31 | if err != errInvalidImageType {
32 | t.Errorf("Expected errInvalidImageType but got %s", err)
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/chapter9/4_benchmarking/image_test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 | "net/http/httptest"
6 | "testing"
7 | )
8 |
9 | func TestImageCreateFromURLInvalidStatusCode(t *testing.T) {
10 | server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
11 | w.WriteHeader(404)
12 | }))
13 | defer server.Close()
14 |
15 | image := Image{}
16 | err := image.CreateFromURL(server.URL)
17 | if err != errImageURLInvalid {
18 | t.Errorf("Expected errImageURLInvalid but got %s", err)
19 | }
20 | }
21 |
22 | func TestImageCreateFromURLInvalidContentType(t *testing.T) {
23 | server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
24 | w.WriteHeader(200)
25 | w.Header().Add("Content-Type", "text/html")
26 | }))
27 | defer server.Close()
28 |
29 | image := Image{}
30 | err := image.CreateFromURL(server.URL)
31 | if err != errInvalidImageType {
32 | t.Errorf("Expected errInvalidImageType but got %s", err)
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/ig/templates/images/new.html:
--------------------------------------------------------------------------------
1 | {{define "images/new"}}
2 |
3 |
4 |
Add An Image
5 | {{if .Error}}
6 |
7 | {{.Error}}
8 |
9 | {{end}}
10 |
25 |
26 |
27 | {{end}}
28 |
--------------------------------------------------------------------------------
/chapter10/0_base/templates/images/new.html:
--------------------------------------------------------------------------------
1 | {{define "images/new"}}
2 |
27 | {{end}}
28 |
--------------------------------------------------------------------------------
/chapter8/0_base/templates/images/new.html:
--------------------------------------------------------------------------------
1 | {{define "images/new"}}
2 |
27 | {{end}}
28 |
--------------------------------------------------------------------------------
/chapter9/0_base/templates/images/new.html:
--------------------------------------------------------------------------------
1 | {{define "images/new"}}
2 |
27 | {{end}}
28 |
--------------------------------------------------------------------------------