huin / goupnp

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

Fail on http post request to router. #32

Closed hyunsooda closed 3 years ago

hyunsooda commented 5 years ago
스크린샷 2019-09-15 오전 3 12 05

In this image, it shows that device(ipTIME N104R3) is detected but http post request was fail. I have a long time to find why my router doesn't response on post request. so I have took a specification about my router but there are no statement related to soap... so I have no idea whether my router cannot response or other problem is there...

Definition of my function

func AddPortMapping_ver1(PrivateIP string, ExternalPort uint16, InternalPort uint16, Protocol string) {
    clients, errors, err := internetgateway1.NewWANIPConnection1Clients()

    if errors != nil {
        return
    }
    if err != nil {
        return
    }
    for _, client := range clients {
        if err := client.AddPortMapping(PrivateIP, ExternalPort, Protocol, InternalPort, PrivateIP, true, "test", 0); err != nil {
            fmt.Println(err.Error())
        }
    }
}

And call AddPortMapping_ver1() in main function

AddPortMapping_ver1("192.168.0.2", 7871, 7871, "TCP") // my computer address is 192.168.0.2 and 192.168.0.1 is address of router

Your library says

스크린샷 2019-09-15 오전 3 22 02

Do you have any idea about this problem?

Sorry for my English.

huin commented 5 years ago

This is a bit of an odd one. It sounds like the router might be responding with a malformed HTTP header when responding to the POST.

To check, you could use a packet sniffer while running your code to look at network traffic between the computer making the SOAP call to the router and the router itself. Maybe filter for traffic to/from 192.168.0.1. You should be able to find an HTTP request that goes to the router.

I suspect from the error that the router is returning a first line response that looks something like:

HTTP1.1 200 OK
<some HTTP headers ...>

The 200 OK bit is irrelevant for this specific error. The HTTP1.1 is what I am focusing on, and it should be HTTP/1.1 (i.e with a slash). If that's the case, then the router's SOAP implementation is buggy. That might be something you can work around, though but first we should confirm if that's the case.

If that's not the case, would you be able to share the HTTP request (and response if there is one) from that single SOAP request?

hyunsooda commented 5 years ago

Hello @huin :) Thanks for kind replying!

스크린샷 2019-09-22 오전 7 49 34

This is packet picture between 192.168.0.1(my router) and 192.168.0.2(my desktop) In this picture, I could see HTTP get method to get InternetGatewayDevice.xml, response on get method(http://192.168.0.1:1780/InternetGatewayDevice.xml) and post method(controlWANIPConnection HTTP1.1)

Picture 2 (Get response on InternetGatewayDevice)

스크린샷 2019-09-22 오전 7 49 41

Picture 3 (HTTP Post)

스크린샷 2019-09-22 오전 7 49 45

Picture 4 (Bad request ...??)

스크린샷 2019-09-22 오전 7 49 51

Can you give an advice based on these information? I will call my router company to figure out whether my router model is supported SOAP response or not tomorrow(today is holiday in Korean time)

huin commented 5 years ago

Interesting. So it confirms my suspicion that the router is returning a badly formed HTTP response. That might be something that could be worked around by injecting a transport into the SOAP client's HTTPClient, but it sounds like it wouldn't be worth doing so because we're getting a 400 bad request anyway. I'm guessing that it's their error response handler that's producing the bad HTTP header, presumably they only tested the success paths.

In terms of getting something working for you, this is tricky: it would be necessary to work out what the router doesn't like about the SOAP request sent by the library. Unfortunately all we've got to go on is "Bad Request". This could mean something that the router didn't like about the HTTP headers or the XML body, it's not clear. Working this out would presumably be trial and error with manually constructed SOAP requests. If that was worked out, then there's the question of how the goupnp library might be adapted to being able to send them. Unfortunately, without knowing exactly what the router is unhappy about there's not much more I can add here :(

hyunsooda commented 5 years ago

Okay... I have last 2 questions :

  1. You mean that this problem is relevant with my router implementation(specifically, my router vendor?)?

  2. I have no experience how your library works because your library functions don't work in my environment. so my question is your 'AddPortMapping' function performs that my router force to open the port given? If so, is this not illegal? is this standard? I know that Ethereum, Bitcoin, Bittorrent have tech like this.

huin commented 5 years ago
  1. Answer: half yes, half unknown.
  1. Answer: I don't know that there's anything wrong with the library, as far as I know, others have managed to use it (or other SOAP functions) for their routers. It's possible that your router doesn't support it - you could check the response XML from http://192.168.0.1:1780/InternetGatewayDevice.xml to see if it's one of the supported methods. Check if that XML contains "AddPortMapping". If not, then it's probably not supported (the goupnp library doesn't actually check the XML). If it is present, then I suspect that it's a problem with how the router parses the HTTP request or the SOAP envelope inside it.
hyunsooda commented 5 years ago

Oh! absolutely there is no 'AddPortMapping' in http://192.168.0.1:1780/InternetGatewayDevice.xml

It means that my router no support AddPortMaping which is standard in UPnP?

I was wondering that AddPortMapping function in your library performs that my router force to open given port? (please answer about this.. I really want to know..! )

huin commented 5 years ago

Ah, that explains it then. I'm not 100% sure, but I think that routers don't have to implement all the features provided. The goupnp library assumes that all the features are provided.

Unfortunately if the router doesn't offer that SOAP method, then the goupnp library won't be able to forward the port.

hyunsooda commented 5 years ago

OK, alright.

The last question that I did is not related to whether your library works well or not.

I know that "AddPortMaping" is a standard function that force router to open given port.

Is your library also implemented this feature?

huin commented 5 years ago

The goupnp library does implement it, yes.

hyunsooda commented 5 years ago

Thanks..

This is really last question...

Do you know why this feature is standard? Some people may dislike that their port is automatically opened by third-party application. I searched about this but there is no reason anywhere.

Sorry for hassle.

hyunsooda commented 5 years ago

Oh! Jesus! I have found the solution :)

The solution is 'miniupnp'

스크린샷 2019-09-22 오후 11 42 08 스크린샷 2019-09-22 오후 11 37 44

Very cool :)

Thanks for very kind replying @huin :)

huin commented 5 years ago

I hope it helped :)