Web програмиране

08.01.2014

HTTP

Протокола

Версии

Всичките ли ги ползваме?

В Go си имаме библиотека

Защо!?

Клиентска част

package main

import (
    "fmt"
    "net/http"
)

func main() {
    resp, err := http.Get("http://fmi.golang.bg/")
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("GET fmi golang site said HTTP %d\n", resp.StatusCode)
}

Интересна част

package main

import (
	"fmt"
	"html"
	"log"
	"net/http"
)

func init() {
	log.Println("Starting webserver")
}

func main() {
    http.HandleFunc("/world", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
    })

    log.Fatal(http.ListenAndServe(":8282", nil))
}

http.ResponseWriter

type ResponseWriter interface {
    // Header returns the header map that will be sent by WriteHeader.
    Header() Header

    // Write writes the data to the connection as part of an HTTP reply.
    Write([]byte) (int, error)

    // WriteHeader sends an HTTP response header with status code.
    WriteHeader(int)
}

http.Request

Ами GET, POST параметрите? Формите?

err := req.ParseForm()
// handle if err != nil
user := req.Form.Get("username")

Повече от един начин да одереш котка

HTTPS

func ListenAndServeTLS(addr string, certFile string, keyFile string, handler Handler) error

Demo Webserver

Темплейти

Пример

Темплейт:

<h1>Editing {{.Title}}</h1>

<form action="/save/{{.Title}}" method="POST">
<div><textarea name="body" rows="20" cols="80">{{printf "%s" .Body}}</textarea></div>
<div><input type="submit" value="Save"></div>
</form>

Изполването му:

func editHandler(w http.ResponseWriter, r *http.Request) {
    p := &Page{
        Title: "Hello, world!",
        Body: "Lorem ipsum dolor sit amet...",
    }
    t, _ := template.ParseFiles("edit.html")
    t.Execute(w, p)
}

text/template vs html/template

text/template

import "text/template"
...
t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>")



Hello, <script>alert('you have been pwned')</script>!

html/template

import "html/template"
...
t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>")



Hello, &lt;script&gt;alert(&#39;you have been pwned&#39;)&lt;/script&gt;!

Сигурност и escaping

Context                          {{.}} After
{{.}}                            O'Reilly: How are &lt;i&gt;you&lt;/i&gt;?
<a title='{{.}}'>                O&#39;Reilly: How are you?
<a href="/{{.}}">                O&#39;Reilly: How are %3ci%3eyou%3c/i%3e?
<a href="?q={{.}}">              O&#39;Reilly%3a%20How%20are%3ci%3e...%3f
<a onx='f("{{.}}")'>             O\x27Reilly: How are \x3ci\x3eyou...?
<a onx='f({{.}})'>               "O\x27Reilly: How are \x3ci\x3eyou...?"
<a onx='pattern = /{{.}}/;'>     O\x27Reilly: How are \x3ci\x3eyou...\x3f

Алтернативи от по-високо ниво

Gorilla

Няколко библиотеки, които ще улеснят живота ви по темата

Beego

Martini

Negroni

"Hello, World!" с Negroni

package main

import (
    "fmt"
    "github.com/codegangsta/negroni"
    "net/http"
)

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
        fmt.Fprintf(w, "Hello, World!")
    })

    // Use the default middleware.
    n := negroni.Classic()
    // ... Add any other middlware here

    // add the router as the last handler in the stack
    n.UseHandler(mux)
    n.Run(":3000")
}

Gin Gonic

Gin Gonic routing

func main() {
    r := gin.Default()

    // Simple group: v1
    v1 := r.Group("/v1")
    {
        v1.POST("/login", loginEndpoint)
        v1.POST("/submit", submitEndpoint)
        v1.POST("/read", readEndpoint)
    }

    // Simple group: v2
    v2 := r.Group("/v2")
    {
        v2.POST("/login", loginEndpoint)
        v2.POST("/submit", submitEndpoint)
        v2.POST("/read", readEndpoint)
    }

    // Listen and server on 0.0.0.0:8080
    r.Run(":8080")
}

Въпроси?