huin / goupnp

UPnP client library for Go (#golang)
BSD 2-Clause "Simplified" License
430 stars 86 forks source link

httpu: error while parsing response #45

Closed MatheusR42 closed 3 years ago

MatheusR42 commented 3 years ago

What is the ideal response format of httpu.conn.ReadFrom? Can someone give me a example?

I am trying to connect to my Yeelight(https://www.yeelight.com/download/Yeelight_Inter-Operation_Spec.pdf) that respond in this way (I copied this from ResponseBytes.string() of VSCode debugger):

HTTP/1.1 200 OK\r\nCache-Control: max-age=3584\r\nDate: \r\nExt: \r\nLocation: yeelight://192.168.1.2:123456\r\nServer: POSIX UPnP/1.0 YGLC/1\r\nid: 0x0000000007fe523f\r\nmodel: color\r\nfw_ver: 26\r\nsupport: get_prop set_default set_power toggle set_bright start_cf stop_cf set_scene cron_add cron_get cron_del set_ct_abx set_rgb set_hsv set_adjust adjust_bright adjust_ct adjust_color set_music set\r\npower: off\r\nbright: 100\r\ncolor_mode: 2\r\nct: 2899\r\nrgb: 16711680\r\nhue: 359\r\nsat: 100\r\nname: \r\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00

But every time I fall into "httpu: error while parsing response: unexpected EOF".

I tried to make a fake response only to test, but I keep falling in "httpu: error while parsing response: unexpected EOF". Here is the change that I made to test with the fake response:

buf := []byte("HTTP/1.1 200 OK\r\n")
response, err := http.ReadResponse(bufio.NewReader(bytes.NewBuffer(buf)), req)
if err != nil {
    log.Printf("httpu: error while parsing response: %v", err)
    continue
}
MatheusR42 commented 3 years ago

I solved it, but I do not know why hahaha

I have to put one more \r\n before the start of the \x00s.

Code:

formatedString := strings.Replace(string(responseBytes), "\r\n\x00", "\r\n\r\n\x00", -1)
formatedByte := []byte(formatedString)

response, err := http.ReadResponse(bufio.NewReader(bytes.NewBuffer(formatedByte)), nil)

Response before this:

HTTP/1.1 200 OK\r\nCache-Control: max-age=3584\r\nDate: \r\nExt: \r\nLocation: yeelight://192.168.1.2:12345\r\nServer: POSIX UPnP/1.0 YGLC/1\r\nid: 0x0000000007fe523f\r\nmodel: color\r\nfw_ver: 26\r\nsupport: get_prop set_default set_power toggle set_bright start_cf stop_cf set_scene cron_add cron_get cron_del set_ct_abx set_rgb set_hsv set_adjust adjust_bright adjust_ct adjust_color set_music set\r\npower: off\r\nbright: 100\r\ncolor_mode: 2\r\nct: 2899\r\nrgb: 16711680\r\nhue: 359\r\nsat: 100\r\nname: \r\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00

Response after this code:

HTTP/1.1 200 OK\r\nCache-Control: max-age=3584\r\nDate: \r\nExt: \r\nLocation: yeelight://192.168.1.2:12345\r\nServer: POSIX UPnP/1.0 YGLC/1\r\nid: 0x0000000007fe523f\r\nmodel: color\r\nfw_ver: 26\r\nsupport: get_prop set_default set_power toggle set_bright start_cf stop_cf set_scene cron_add cron_get cron_del set_ct_abx set_rgb set_hsv set_adjust adjust_bright adjust_ct adjust_color set_music set\r\npower: off\r\nbright: 100\r\ncolor_mode: 2\r\nct: 2899\r\nrgb: 16711680\r\nhue: 359\r\nsat: 100\r\nname: \r\n\r\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00

If someone knows why did this work tell me! hahaha

huin commented 3 years ago

This looks like a HTTP response formatting issue with the fake data you're supplying, perhaps. There's supposed to be two \r\n after the HTTP headers and immediately before the response payload.

huin commented 3 years ago

Ah - if that's the literal response data you're getting from the device, then the device is formatting its response wrong. That's fiddly.

MatheusR42 commented 3 years ago

I think that it's it @huin. Thanks for the goupnp package! It helped me a lot to do the integration! :)