Search code examples
goproxyvpncloud-foundrybeego

Golang Dialer in Cloud Foundry


I am trying to access a URL that gives me a JSON response, and said URL is only accessible when I am connected to my company's VPN.

Using the Standard Golang Library, the code below is getting an error even when I am connected to my company's VPN:

myClient := &http.Client{}
req, err := http.NewRequest("POST", "https://mysite/getJSONResponse", nil)    
req.Header.Add("myHeader", "myHeaderValue")
resp, err := myClient.Do(req)

Here is the error I am getting:

502 Bad Gateway: Registered endpoint failed to handle the request.

However, this code (also from the Standard Library) is able to get the JSON response when I am connected to my company's VPN:

envDialer := proxy.FromEnvironment()    
myTransport := &http.Transport{Dial: envDialer.Dial}
myClient := &http.Client{Transport: myTransport}
req, err := http.NewRequest("POST", "https://mysite/getJSONResponse", nil)
req.Header.Add("myHeader", "myHeaderValue")
resp, err := myClient.Do(req)

My problem is that when I push the working code to Cloud Foundry (which is also connected to my company's VPN), my code is getting the below error instead:

Post https://mysite/getJSONResponse: read tcp 10.254.2.182:45320->165.156.25.94:443:
read: connection reset by peer

It is as if the code is unable to connect to my company's VPN even when it is already Pushed to Cloud Foundry, which is why the URL refused to give the JSON response.

However, when I try to access the same URL in Cloud Foundry with a test Web Application that uses the Beego framework, it is able to get the JSON response just fine.

I should mention that the Beego version works even when the http_proxy, https_proxy, and no_proxy environment variables are not set:

req := httplib.Post("https://mysite/getJSONResponse")
req.Header("myHeader", "myHeaderValue")

str, err := req.String()
if err != nil {
    fmt.Println(err)
}

beego.Info(str)
u.Data["json"] = str
u.ServeJSON()

My questions are:

  1. Why is the second Standard Library code working fine locally, but not when Pushed to Cloud Foundry?

  2. What is the Beego framework doing behind the scenes that lets it connect to my company's VPN over at Cloud Foundry, and can the same be done with the Standard Library?

I've got a feeling Beego is doing something to its Proxy/Port settings to enable it to connect to our company's VPN.

I really don't want to have to integrate our back-end codes with the Beego framework just to connect to our company's VPN. I must be missing something really simple which can be done with the Standard Library. Any ideas?


Solution

  • I finally managed to get it to work using only the beego/httplib package, so there was no need to integrate the entire Beego framework (thank goodness). Here is my code:

    import (
        "github.com/astaxie/beego/httplib"
    )
    
    -----------------------------------------------------
    
    req := httplib.Post("https://mysite/getJSONResponse")
    req.Header("myHeader", "myHeaderValue")
    
    str, err := req.String()
    
    if err == nil {
        strBytes := []byte(str)
        // Do something with the JSON response.
    }
    

    I do not have time to investigate what makes the httplib package work, although I have seen that it only uses the Standard Library to Dial the appropriate connections to make Requests. Could somebody help shed some light on this?

    EDIT: I see that it uses the crypto/tls package's *tls.Config to set up a connection with the appropriate Certificates. This may be how it makes Requests that connect to our VPN.