Umlauts in ISO-8859-1 encoded website - http

My very simple code snippet:
import "net/http"
import "io"
import "os"
func main() {
resp, err := http.Get("http://example.com")
if err == nil {
io.Copy(os.Stdout, resp.Body)
}
}
When example.com is charset=iso-8859-1 encoded my output is faulty. Umlauts for example are not displayed correctly:
Hällo Wörld --> H?llo W?rld
Whats a good solution to display umlauts correctly??

You can use the package golang.org/x/net/html/charset to determine the encoding of the website, and also create a reader that converts the content to UTF-8.
Below is a working example:
package main
import (
"io"
"net/http"
"os"
"golang.org/x/net/html/charset"
)
func main() {
resp, err := http.Get("http://example.com")
if err != nil {
os.Exit(1)
}
r, err := charset.NewReader(resp.Body, resp.Header.Get("Content-Type"))
if err != nil {
os.Exit(1)
}
io.Copy(os.Stdout, r)
}

Related

How to Write Files or Folder to IPFS via the HTTP API

I'm confused about the HTTP API docs of IPFS。next is part of it。
/api/v0/add
Add a file or directory to IPFS.
//but how to add a directory by golang? it look like so simple but no a example to finish it
#cURL Example
curl -X POST -F file=#myfile "http://127.0.0.1:5001/api/v0/add?quiet=&quieter=&silent=&progress=&trickle=&only-hash=&wrap-with-directory=&chunker=size-262144&pin=true&raw-leaves=&nocopy=&fscache=&cid-version=&hash=sha2-256&inline=&inline-limit=32"
I worked on the same issue and found this working shell solution:
https://community.infura.io/t/ipfs-http-api-add-directory/189/8
you can rebuild this in go
package main
import (
"bytes"
"github.com/stretchr/testify/assert"
"io"
"io/ioutil"
"mime/multipart"
"net/http"
"os"
"strings"
"testing"
)
func TestUploadFolderRaw(t *testing.T) {
ct, r, err := createForm(map[string]string{
"/file1": "#/my/path/file1",
"/dir": "#/my/path/dir",
"/dir/file": "#/my/path/dir/file",
})
assert.NoError(t, err)
resp, err := http.Post("http://localhost:5001/api/v0/add?pin=true&recursive=true&wrap-with-directory=true", ct, r)
assert.NoError(t, err)
respAsBytes, err := ioutil.ReadAll(resp.Body)
assert.NoError(t, err)
t.Log(string(respAsBytes))
}
func createForm(form map[string]string) (string, io.Reader, error) {
body := new(bytes.Buffer)
mp := multipart.NewWriter(body)
defer mp.Close()
for key, val := range form {
if strings.HasPrefix(val, "#") {
val = val[1:]
file, err := os.Open(val)
if err != nil { return "", nil, err }
defer file.Close()
part, err := mp.CreateFormFile(key, val)
if err != nil { return "", nil, err }
io.Copy(part, file)
} else {
mp.WriteField(key, val)
}
}
return mp.FormDataContentType(), body, nil
}
or use https://github.com/ipfs/go-ipfs-http-client which seems to be a better way. I'm working on it and tell you when I know how to use it
Greetings

Get Request in Golang

this is a textbook example I try to put in use.
I get "BAD" as a result, it means that resp is nil, though I don't know how to fix it.
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
)
func main() {
resp, _ := http.Get("http://example.com/")
if resp != nil {
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
resp.Body.Close()
} else {
fmt.Println("BAD")
}
}
I would recommend to check your Internet settings first, as I cannot reproduce the problem.
Also, error handling in Go is crucial, so change your code to the one below and see if you get any error when making the request.
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
)
func main() {
resp, err := http.Get("http://example.com/")
if err != nil {
log.Fatalln(err)
}
if resp != nil {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatalln(err)
}
fmt.Println(string(body))
resp.Body.Close()
} else {
fmt.Println("BAD")
}
}

Render an image from base64 in golang

I would like to render an image from base64 in golang (here the twitter icon)
package main
import (
base64 "encoding/base64"
"fmt"
"io"
"net/http"
"strconv"
)
func pix(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
var cookie *http.Cookie
cookie, err := r.Cookie("csrftoken")
if err != nil {
fmt.Printf("error")
fmt.Println(err)
}
fmt.Printf(cookie.Value)
w.Header().Set("Content-Type", "image/jpeg")
p, err := base64.StdEncoding.DecodeString("iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAADMUlEQVRYw+2YTUgUYRjHZzOJIoNA+rrUyYNIRQgRHaLo4qFDBEGeunSxS9TFU0QEnhIh6IvokrUzO2uamRmbG6XmR/mVaKZpZVbYvvO143zszsxOz+yahNm+785sITEP72F3Z+adH8/zf5+PpagwtxKXj+Vj+Vg+lo/lY+W+WI4KpddKwWIQFUSF97nNLcLGZt75SiOHchEXfskDVmYjlowpiEoei3UT2ljcFJOpOd169C1Z2SuvgsdpB7cgzB16EV/byGM2xDIVPxQujKmBDF/2m2l0vFvmEin7N2v8kiiPiOeGlGHRvP1RdxA9eYtGR7pk2Pf6lI7RCoP2RaWkZWe3fsFc18hvesAHPGEFUc24ltnx3kyiCJwfRMs6dTXLdSIjO9Osal18qzKfE5V9coDxhlU7qS3uOyiaB55JDtkS2TKoLCLaOLPS4b02pQdCHiUfRKf653/d2kjZN6f10jYxI2EnrGk5H+2WsVi6ZZ8fVSmGQKaYyyFuR6ugmUtVrJo2C7HokeGq8447sYpOPBbo3XFzKC95626sZlz905sUM9XLGbXvtKtTOhZrQDApkhNNkiAOPo/viojh2YSZsj1aF2eQ5n2stuomNQjiiGQanrFufdCXP8gu8tbhjridJ6saVPKExXJrwlwfb3pnAg2Ut0tEBZFI8gza81Tik15DCDIoINQ7aQdBo90RMfrdwNaWLFY9opJGkBQrhCA/HXspQ8W1XHkN6vfWFiGH9ouwhdpJUFuy2JX3eg6uyqENpNHZYcUd02jcLMI2WO67UwZVv1G1HLMq3L83KuEbLPdY7IL2L42p0MMQiuzkq/ncwucOi6qPbWkWoPfCUsENpweUnP1EmE4XGhgagT72RyXolkSCHBbTU3By3fgJj8VyJW3CmSHl8oTWMJuYUUizVvtcsuyJ6J4J663CMLevXar/lJgnKNSgbphzKjriTn5i0F8eX9ODXnEzf6JHvjGtv+aNGdWCOEKnJRmpr5oFVQV8WTWglIKHMlPhv5uqQ1xGYfB5fRMPo+n2VmFbi7ChiS9oWBhZvXrI01TNLg7yPxt51v9rxMfysXwsH8vH+g+wfgDUr+5LcyNV4AAAAABJRU5ErkJggg==")
if err != nil {
http.Error(w, "internal error", 500)
return
}
w.Header().Set("Content-Length", strconv.Itoa(len(p))) //len(dec)
io.WriteString(w, string(p))
}
func main() {
http.HandleFunc("/pix/", pix)
err := http.ListenAndServe(":9080", nil)
if err != nil {
fmt.Println(err)
}
}
But it doesn't display anything and when I try to go to the URL; it downloads a file that contains error. Anyone have any idea why this is?
You are writing data to client other than the image. Specifically, this line:
fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
You browser tries to render the content as a JPEG, but fails because of this extra data, so it prompts you to download it instead. Remove it and the picture will be displayed correctly.
You should also follow #Mellow Marmot's suggestion and use w.Write(p) instead of io.WriteString(w, string(p)).

Golang Error: Undefined: http.NewSingleHostReverseProxy

I tried building a simple program using Golang, here it is:
package main
import (
"net/http"
"net/http/httputil"
"log"
)
func main(){
proxy := http.NewSingleHostReverseProxy( &http.URL{Scheme:"http",Host:"www.google.com",Path:"/"})
err := http.ListenAndServe(":8080", proxy)
if err != nil {
log.Fatal("ListenAndServe: ", err.String())
}
}
Build:
go build myprogram.go
Output:
command-line-arguments
./myprogram.go:5: imported and not used: "net/http/httputil"
./myprogram.go:11: undefined: http.NewSingleHostReverseProxy
./myprogram.go:11: undefined: http.URL
./myprogram.go:15: err.String undefined (type error has no field or method String)
I noticed that http.NewSingleHostReverseProxy is in the "net/http/httputil" package, so why did I see such errors?
Maybe I need a specific command to build it correctly?
EDIT
Afterwords, here is the new working code:
package main
import (
"net/http"
"net/http/httputil"
"net/url"
"log"
)
func main(){
proxy := httputil.NewSingleHostReverseProxy( &url.URL{Scheme:"http",Host:"www.google.com",Path:"/"})
err := http.ListenAndServe(":8080", proxy)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
I added
"net/url"
And replaced http.NewSingleHostReverseProxy with httputil.NewSingleHostReverseProxy, also
http.URL with url.URL.
This is the working code:
package main
import (
"net/http"
"net/http/httputil"
"net/url"
"log"
)
func main(){
proxy := httputil.NewSingleHostReverseProxy( &url.URL{Scheme:"http",Host:"www.google.com",Path:"/"})
err := http.ListenAndServe(":8080", proxy)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
Thanks to raina77ow for help.

How to write `cat` in Go using pipes

I have an implementation of the Unix tool cat below. It reads a number of bytes from os.Stdin into a buffer, then writes those bytes out to os.Stdout. Is there a way I can skip the buffer and just pipe Stdin directly to Stdout?
package main
import "os"
import "io"
func main() {
buf := make([]byte, 1024)
var n int
var err error
for err != io.EOF {
n, err = os.Stdin.Read(buf)
if n > 0 {
os.Stdout.Write(buf[0:n])
}
}
}
You can use io.Copy() (Documentation here)
Example:
package main
import (
"os"
"io"
"log"
)
func main() {
if _, err := io.Copy(os.Stdout, os.Stdin); err != nil {
log.Fatal(err)
}
}
For example,
package main
import (
"io"
"os"
)
func main() {
io.Copy(os.Stdout, os.Stdin)
}

Resources