tcpで取得したデータをParseする

net.Dialで取得したデータは以下のようなフォーマットで取得されてしまう。Body/headerにわけて取得したい場合は、どうしたらいいだろうか?

package main

import (
    "io"
    "net"
    "os"
)

func main() {
    conn, _ := net.Dial("tcp", "ascii.jp:80")
    conn.Write([]byte("GET/ HTTP/1.0\r\nHOST: ascii.jp\r\n\r\n"))
    io.Copy(os.Stdout, conn)

}
HTTP/1.1 400 Bad Request
Server: CloudFront
Date: Mon, 13 Jul 2020 09:58:14 GMT
Content-Type: text/html
Content-Length: 915
Connection: close
X-Cache: Error from cloudfront
Via: 1.1 2a2a0145d534dcf7dbfa42697b2f26a3.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: NRT20-C2
X-Amz-Cf-Id: Z57VNBeDUWuqOMzNyT4xyBMZocBjF0MriwGnbykTlQEWJWidTAC2iQ==

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<TITLE>ERROR: The request could not be satisfied</TITLE>
</HEAD><BODY>
<H1>400 ERROR</H1>
<H2>The request could not be satisfied.</H2>
<HR noshade size="1px">
Bad request.
We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
<BR clear="all">
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
<BR clear="all">
<HR noshade size="1px">
<PRE>
Generated by cloudfront (CloudFront)
Request ID: Z57VNBeDUWuqOMzNyT4xyBMZocBjF0MriwGnbykTlQEWJWidTAC2iQ==
</PRE>
<ADDRESS>
</ADDRESS>
</BODY></HTML>

httpのレスポンスをParseするhttp.ReadResponseを用いることでBody/headerなどにParseすることができる.

package main

import (
    "bufio"
    "io"
    "net"
    "net/http"
    "os"
)

func main() {
    conn, _ := net.Dial("tcp", "ascii.jp:80")
    conn.Write([]byte("GET/ HTTP/1.0\r\nHOST: ascii.jp\r\n\r\n"))
    buf := bufio.NewReader(conn)
    r, err := http.ReadResponse(buf, nil)
    defer r.Body.Close()
    if err != nil {
        panic(err)
    }
    io.Copy(os.Stdout, r.Body)
}

出力は以下のようになる

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<TITLE>ERROR: The request could not be satisfied</TITLE>
</HEAD><BODY>
<H1>400 ERROR</H1>
<H2>The request could not be satisfied.</H2>
<HR noshade size="1px">
Bad request.
We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
<BR clear="all">
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
<BR clear="all">
<HR noshade size="1px">
<PRE>
Generated by cloudfront (CloudFront)
Request ID: eQbevlpJLncU-QYjaARYHCkWBUvAhTMyU1ov-FTsG3af1eoTbPBxlA==
</PRE>
<ADDRESS>
</ADDRESS>
</BODY></HTML>

jsonデータをhttpで表示する

Golangjsonデータをhttpで表示する

json.NewEncoder を使う.ファイルに書き込むときと同じようにio.Writer interfaceをもつhttp.ResponseWriterを引数にする.

package main

import (
    "encoding/json"
    "net/http"
    "os"
)

func handler(w http.ResponseWriter, r *http.Request) {
    encoder := json.NewEncoder(w)
    encoder.SetIndent("", " ")
    encoder.Encode(map[string]string{
        "golang": "great language",
        "python": "great community",
    })
        // headerを標準出力にだす
    r.Header.Write(os.Stdout)
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)

}