英文:
Golang HTTPS/TLS POST client/server
问题
我已经写了一个简单的Go客户端/服务器,可以通过TLS进行HTTP GET,但我也想让它能够通过TLS进行HTTP POST。
在下面的示例中,index.html
只包含文本hello
,HTTP GET正常工作。我希望客户端能够获取HTTP GET并将hello world
写回服务器。
客户端:
package main
import (
"crypto/tls"
"fmt"
"io/ioutil"
"net/http"
"strings"
)
func main() {
link := "https://10.0.0.1/static/index.html"
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}
response, err := client.Get(link)
if err != nil {
fmt.Println(err)
}
defer response.Body.Close()
content, _ := ioutil.ReadAll(response.Body)
s := strings.TrimSpace(string(content))
fmt.Println(s)
out := s + " world"
resp, err := client.Post(link, "text/plain", strings.NewReader(out))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
// 处理POST响应
// ...
}
服务器:
package main
import (
"fmt"
"log"
"net/http"
)
func main() {
http.HandleFunc("/static/", func(w http.ResponseWriter, r *http.Request) {
fmt.Println("Got connection!")
http.ServeFile(w, r, r.URL.Path[1:])
})
log.Fatal(http.ListenAndServeTLS(":443", "server.crt", "server.key", nil))
}
我目前还没有处理服务器端的POST请求,但我只是希望它将其打印到屏幕上,这样当我运行客户端时,我将看到服务器打印出hello world
。
如何修复我的客户端代码以进行正确的POST?相应的服务器代码应该是什么样的以接受POST请求?任何帮助将不胜感激,我很难找到HTTPS/TLS POST的示例。
英文:
I have written a simple client/server in Go that will do an HTTP GET over TLS, but I'm trying to also make it capable of doing an HTTP POST over TLS.
In the example below index.html
just contains the text hello
, and the HTTP GET is working fine. I want the client to get the HTTP GET and write back, hello world
to the server.
client
package main
import (
"crypto/tls"
"fmt"
"io/ioutil"
"net/http"
"strings"
)
func main() {
link := "https://10.0.0.1/static/index.html"
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}
response, err := client.Get(link)
if err != nil {
fmt.Println(err)
}
defer response.Body.Close()
content, _ := ioutil.ReadAll(response.Body)
s := strings.TrimSpace(string(content))
fmt.Println(s)
// out := s + " world"
// Not working POST...
// resp, err := client.Post(link, "text/plain", &out)
}
server
package main
import (
"fmt"
"log"
"net/http"
)
func main() {
http.HandleFunc("/static/", func (w http.ResponseWriter, r *http.Request) {
fmt.Println("Got connection!")
http.ServeFile(w, r, r.URL.Path[1:])
})
log.Fatal(http.ListenAndServeTLS(":443", "server.crt", "server.key", nil))
}
I also currently have nothing to handle the POST on the server side, but I just want it to print it out to the screen so when I run the client I will see the server print hello world
.
How should I fix my client code to do a proper POST? And what should the corresponding server code look like to accept the POST? Any help would be appreciated, I'm having trouble finding HTTPS/TLS POST examples.
答案1
得分: 2
你没有分享错误信息,但我猜测client.Post
调用不允许将字符串作为其第三个参数,因为它需要一个io.Reader
。请尝试使用以下代码:
out := s + " world"
resp, err := client.Post(link, "text/plain", bytes.NewBufferString(out))
在服务器端,你已经设置了正确的代码来处理POST请求。只需检查请求的方法:
http.HandleFunc("/static/", func (w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
// 处理POST请求
} else {
// 处理其他请求
}
})
我注意到还有另一个问题。在这里使用index.html
可能行不通。http.ServeFile
会重定向该路径。请参考https://golang.org/pkg/net/http/#ServeFile:
> 作为特例,ServeFile会将任何以"/index.html"结尾的请求重定向到相同的路径,但不包括最后的"index.html"。要避免这种重定向,要么修改路径,要么使用ServeContent。
我建议使用不同的文件名来避免这个问题。
英文:
You didn't share the error message, but I assume the client.Post
call wasn't allowing a string as its third parameter, because it requires an io.Reader
. Try this instead:
out := s + " world"
resp, err := client.Post(link, "text/plain", bytes.NewBufferString(out))
On the server side, you already have the right code set up to handle the POST request. Just check the method:
http.HandleFunc("/static/", func (w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
// handle POST requests
} else {
// handle all other requests
}
})
I noticed one other issue. Using index.html
probably won't work here. http.ServeFile
will redirect that path. See https://golang.org/pkg/net/http/#ServeFile:
> As a special case, ServeFile redirects any request where r.URL.Path
> ends in "/index.html" to the same path, without the final
> "index.html". To avoid such redirects either modify the path or use
> ServeContent.
I'd suggest just using a different file name to avoid that issue.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论