-
Notifications
You must be signed in to change notification settings - Fork 17.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
x/net/http2: panic: interface conversion: http.http2Frame is *http.http2UnknownFrame, not *http.http2HeadersFrame #31986
Comments
@zhangriyueming - Can you give us a complete code sample that reproduces this error, and not a snippet of it ? |
@agnivade - Thanks for your response. But I don't have something to "reproduce this error". It's stochastic. The whole program can either works for hundred hours just fine, or throw that panics at just beginning or in one hour. It might be related to the network environment or something. There was another panic. Located to But now I have no idea why this The snippet I posted contains all and only things related to |
Yes, I understand it is not deterministic. I just wanted the entire program rather than a part of it so it becomes easy for us to debug it. If you cannot share the entire program, perhaps you can cut out just this part from it and make an independent program ? |
package main
import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/http/cookiejar"
"net/url"
"strings"
"time"
)
type Transport struct {
upstream http.RoundTripper
jar http.CookieJar
delay int
userAgent string
}
func NewTransport(upstream http.RoundTripper) (*Transport, error) {
jar, err := cookiejar.New(nil)
if err != nil {
return nil, err
}
userAgent := "Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0"
return &Transport{
upstream: upstream,
jar: jar,
delay: 8,
userAgent: userAgent}, nil
}
func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) {
resp, err := t.upstream.RoundTrip(r)
if err != nil {
return nil, err
}
if resp.StatusCode == 503 &&
strings.HasPrefix(resp.Header.Get("Server"), "cloudflare") {
req, err := http.NewRequest("GET", "https://www.google.co.jp/", nil)
if err != nil {
return nil, err
}
client := http.Client{
Transport: t,
Jar: t.jar,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
resp, err = client.Do(req)
if err != nil {
return nil, err
}
redirectUrl := resp.Header.Get("Location")
redirectLocation, err := url.Parse(redirectUrl)
if err != nil {
return nil, err
}
if redirectLocation.Host == "" {
redirectUrl = fmt.Sprintf("%s://%s%s",
resp.Request.URL.Scheme,
resp.Request.URL.Host,
redirectUrl)
}
req, err = http.NewRequest("GET", redirectUrl, nil)
if err != nil {
return nil, err
}
client = http.Client{
Transport: t,
Jar: t.jar,
}
resp, err = client.Do(req)
return resp, err
}
return resp, err
}
type Job struct {
baseUrl string
transport *Transport
client *http.Client
clientWithTransport *http.Client
}
type Response struct {
Key1 string `json:key1`
Key2 string `json:key2`
Key3 string `json:key3`
}
func (job *Job) syncPart1(v interface{}) error {
req, err := http.NewRequest("GET", job.baseUrl+"part1", nil)
resp, err := job.client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
decErr := json.NewDecoder(resp.Body).Decode(v)
if decErr == io.EOF {
decErr = nil // ignore EOF errors caused by empty response body
}
if decErr != nil {
err = decErr
}
return err
}
func (job *Job) syncPart2() ([]byte, error) {
req, err := http.NewRequest("GET", job.baseUrl+"part2", nil)
if err != nil {
return nil, err
}
resp, err := job.clientWithTransport.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return body, nil
}
func (job *Job) Sync() {
var r Response
job.syncPart1(&r)
job.syncPart2()
}
func NewJob() *Job {
http.DefaultTransport.(*http.Transport).Proxy = nil
transport, _ := NewTransport(http.DefaultTransport)
return &Job{
baseUrl: "https://www.google.com/",
transport: transport,
client: &http.Client{},
clientWithTransport: &http.Client{Transport: transport},
}
}
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Greeting! %s", r.URL.Path[1:])
}
func main() {
job := NewJob()
go func() {
for {
job.Sync()
time.Sleep(20 * time.Second)
}
}()
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
} @agnivade - If this is what you meant. |
@agnivade - This panic is very rarely. It often jumped out after dozens days running. So it makes harder to catch it. And I still think it associated to specific environment. And if we know which situation will cause this error message would be very helpful. |
I don't see how this can happen (the @zhangriyueming, can you run your program under the race detector? https://blog.golang.org/race-detector @fraenkel, @tombergan, you see anything I'm missing? |
@bradfitz, I'm looking around an approach to run a reduced or minimal version under the race detector since it will cause 10 times CPU/Memory expensive. At the mean time, I got another panic #32004, I think these may be linked and related. And the other one I mentioned above, there was a panic |
Btw, the program is running in a docker container, if it mights. |
I don't see how either of these are possible, so I suspect some sort of memory corruption. Please post a full repro and/or run with the race detector and see if you have any data races. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
It is randomly occurred. Sometimes works fine without error, sometimes panics.
Maybe it associated with my Transport.
What did you expect to see?
Works without panics.
What did you see instead?
The text was updated successfully, but these errors were encountered: