Golang http Programming

web workflows

  • Works Web server can be summarized as simply
    • Client establishes to the server via TCP / IP protocol TCP connection
    • The client sends to the server HTTP protocol request packet, the requesting server resources in the document
    • The server sends to the client HTTP protocol response packet, if the requested resource contains dynamic language content, the server calls the interpretation engine handles "dynamic content" dynamic languages, and processing the resulting data back to the client
    • Client and server is disconnected. By the client interprets the HTML document, the result of rendering graphics on the client screen

HTTP protocol

  • Hypertext Transfer Protocol (HTTP, HyperText Transfer Protocol) is the Internet's most widely used network protocol, which details the rules of mutual communication between the browser and the Web server, the World Wide Web document transfer protocol to transfer data via the Internet
  • HTTP protocol over the TCP protocol usually carried

http server

package main

import (
    "fmt"
    "net/http"
)

// /go handler
func goHandler(w http.ResponseWriter, r *http.Request) {
    // 获取远程地址
    fmt.Println(r.RemoteAddr, "连接成功")
    // 获取请求类型
    fmt.Println("请求方法: ", r.Method)
    // 获取url路径
    fmt.Println("url path: ", r.URL.Path)
    // 获取header数据
    fmt.Println("header: ", r.Header)
    // 获取请求body内容
    fmt.Println("body: ", r.Body)

    // 返回信息
    _, _ = w.Write([]byte("hello world"))
}

func main()  {
    // 单独写回掉函数
    http.HandleFunc("/go", goHandler)

    // 启动http监听
    _ = http.ListenAndServe("127.0.0.1:8000", nil)
}

http client package

package main

import (
    "fmt"
    "io"
    "net/http"
)

func main() {
    resp, err := http.Get("http://127.0.0.1:8000/go")
    if err != nil {
        fmt.Println("获取数据失败, err: ", err)
        return
    }
    defer resp.Body.Close()
    // 获取http状态码
    fmt.Println("status: ", resp.Status)
    // 获取header信息
    fmt.Println("header: ", resp.Status)

    buf := make([]byte, 124)
    for {
        // 接收服务端数据
        n, err := resp.Body.Read(buf)

        fmt.Println(string(buf[:n]))

        if err == io.EOF {
            break
        }

        if err != nil {
            fmt.Println("数据读取失败, err: ", err)
            continue
        }
    }
}

tcp package implements the client

package main

import (
    "fmt"
    "io"
    "net"
)

func main() {
    conn, err := net.Dial("tcp", "127.0.0.1:8000")
    if err != nil {
        fmt.Println("connect err: ", err)
        return
    }
    defer conn.Close()
    msg := "GET /go HTTP/1.1\r\n"
    msg += "Host: 127.0.0.1:8000\r\n"
    msg += "Connection: close\r\n"
    msg += "\r\n\r\n"

    _, err = io.WriteString(conn, msg)
    if err != nil {
        fmt.Println("write string failed, ", err)
        return
    }
    buf := make([]byte, 4096)
    for {
        n, err := conn.Read(buf)
        if err == io.EOF {
            break
        }
        if err != nil {
            fmt.Println("recv data has err, ", err)
            break
        }
        fmt.Println(string(buf[:n]))
    }
}

Other error

golang GET 出现 x509: certificate signed by unknown authority

We Go write a program to try to establish a connection and communication with the HTTPS server.

//gohttps/4-https/client1.go
package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
)

func main() {
    resp, err := http.Get("https://localhost:8081")
    if err != nil {
        fmt.Println("error:", err)
        return
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}

Run this client, we get the following error:

$go run client1.go
error: Get https://localhost:8081: x509: certificate signed by unknown authority

At this point the server error log also gives tips:

2015/04/30 16:03:31 http: TLS handshake error from 127.0.0.1:62004: remote error: bad certificate

Obviously from the client point of view the log, go to realize the default is Client-server To pass over the digital certificate verification, but the client Note: This certificate is issued by an unknown CA's!

Client1.go we can modify the code so that client-side skip the check for certificates:

//gohttps/4-https/client2.go
package main

import (
"crypto/tls"
"fmt"
"io/ioutil"
"net/http"
)

func main() {
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}
resp, err := client.Get("https://localhost:8081")

    if err != nil {
        fmt.Println("error:", err)
        return
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))

}

, Client server certificate will not be verified by setting to true the InsecureSkipVerify tls.Config. Implementation of the results also confirmed this:

$go run client2.go
Hi, This is an example of http service in golang!

http request header set

package main
import (
    "fmt"
    "io/ioutil"
    "net/http"
    "os"
    "encoding/json"
)

func main() { //生成client 参数为默认
    client := &http.Client{}
    //生成要访问的url
    url := "http://somesite/somepath/"
    //提交请求
    reqest, err := http.NewRequest("GET", url, nil)

    //增加header选项
    reqest.Header.Add("Cookie", "xxxxxx")
    reqest.Header.Add("User-Agent", "xxx")
    reqest.Header.Add("X-Requested-With", "xxxx")

    if err != nil {
        panic(err)
    }
    //处理返回结果
    response, _ := client.Do(reqest)
    defer response.Body.Close()
}

http proxy requests

package main

import (
    "crypto/tls"
    "fmt"
    "io"
    "net/http"
    "net/url"
    "time"
)

// http proxy get方法
func httpProxyGet(dataUrl, proxyIp string) (data []byte,  err error) {
    transport := &http.Transport{
        TLSClientConfig:   &tls.Config{InsecureSkipVerify: true}, //ssl证书报错问题
        DisableKeepAlives: false,                                 //关闭连接复用,因为后台连接过多最后会造成端口耗尽
        MaxIdleConns:      -1,                                    //最大空闲连接数量
        IdleConnTimeout:   time.Duration(5 * time.Second),        //空闲连接超时时间
        Proxy: http.ProxyURL(&url.URL{
            Scheme: "http",
            Host:   proxyIp,
        }),
    }
    // 设置代理方式二
    //proxyUrl, _ := url.Parse("http://" + proxyIp)
    //transport.Proxy = http.ProxyURL(proxyUrl)

    // 创建http客户端
    client := &http.Client{
        Timeout:   time.Duration(30 * time.Second),
        Transport: transport,
    }

    request, err := http.NewRequest("GET", dataUrl, nil)
    if err != nil {
        return
    }
    // 请求数据
    resp, err := client.Do(request)
    if err != nil {
        err = fmt.Errorf("request %s, proxyIp: (%s),err: %v", dataUrl, proxyIp, err)
        return
    }
    defer resp.Body.Close()
    // 读取数据
    buf := make([]byte, 128)
    data = make([]byte, 0, 2048)
    for {
        n, err := resp.Body.Read(buf)
        data = append(data, buf[:n]...)

        if err == io.EOF {
            break
        }
        if err != nil {
            continue
        }
    }
    return
}


func main() {
    data, err := httpProxyGet("http://www.baidu.com/", "89.22.11.55:9000")
    if err != nil {
        println(err)
        return
    }
    fmt.Println(string(data))
}

websocket Programming

What is webSocket

  • WebSocket protocol is a full duplex communication over a single TCP connection
  • WebSocket enables exchange of data between the client and the server easier, allowing the server to the client actively push data
  • In the WebSocket API, the browser and the server only needs to complete a handshake, you can directly create a persistent connection between the two, and two-way data transmission
  • You need to install third-party packages:
    • cmd in:go get -u -v github.com/gorilla/websocket

webSocket example

Server

package main

import (
    "github.com/gorilla/websocket"
    "log"
    "net/http"
)

var upgrader = websocket.Upgrader{  // 配置websocker选项
    // 允许websocket跨域
    CheckOrigin: func(r *http.Request) bool {
        return true
    },
}

func echo(w http.ResponseWriter, r *http.Request) {
    c, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Print("upgrade:", err)
        return
    }
    defer c.Close()
    for {
        mt, message, err := c.ReadMessage()
        if err != nil {
            log.Println("read:", err)
            break
        }
        log.Printf("recv: %s", message)
        err = c.WriteMessage(mt, message)
        if err != nil {
            log.Println("write:", err)
            break
        }
    }
}
func main() {
    log.SetFlags(0)
    http.HandleFunc("/echo", echo)
    log.Fatal(http.ListenAndServe("127.0.0.1:8081", nil))
}

html client

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>websocket demo</title>
  </head>
  <body>
    <table>
      <tr>
        <td valign="top" width="50%">
          <p>
            Click "Open" to create a connection to the server, "Send" to send a
            message to the server and "Close" to close the connection. You can
            change the message and send multiple times.
          </p>
          <form>
            <button id="open">Open</button>
            <button id="close">Close</button>
            <input id="input" type="text" value="Hello world!" />
            <button id="send">Send</button>
          </form>
        </td>
        <td valign="top" width="50%">
          <div id="output"></div>
        </td>
      </tr>

      <script>
        window.addEventListener('load', function(evt) {
          var output = document.getElementById('output')
          var input = document.getElementById('input')
          var ws
          var print = function(message) {
            var d = document.createElement('div')
            d.innerHTML = message
            output.appendChild(d)
          }
          document.getElementById('open').onclick = function(evt) {
            if (ws) {
              return false
            }
            ws = new WebSocket('ws://127.0.0.1:8081/echo')
            ws.onopen = function(evt) {
              print('OPEN')
            }
            ws.onclose = function(evt) {
              print('CLOSE')
              ws = null
            }
            ws.onmessage = function(evt) {
              print('RESPONSE: ' + evt.data)
            }
            ws.onerror = function(evt) {
              print('ERROR: ' + evt.data)
            }
            return false
          }
          document.getElementById('send').onclick = function(evt) {
            if (!ws) {
              return false
            }
            print('SEND: ' + input.value)
            ws.send(input.value)
            return false
          }
          document.getElementById('close').onclick = function(evt) {
            if (!ws) {
              return false
            }
            ws.close()
            return false
          }
        })
      </script>
    </table>
  </body>
</html>

Guess you like

Origin www.cnblogs.com/zhichaoma/p/12509733.html