GAE Golang — вызов HTTP JSON RPC работает в dev_appserver, но не в App Engine?

Я создаю приложение Go Google App Engine, которое будет выполнять вызовы HTTP JSON RPC к Биткойн-сервер. Я заставил свой код правильно работать на dev_appserver, но при развертывании в GAE код, похоже, не работает. Я использую библиотеку, доступную на GitHub и назовите его следующим образом:

func GetInfo(id interface{})(map[string]interface{}, os.Error){
    resp, err:=httpjsonrpc.Call("user:[email protected]:18332", "getinfo", id, nil)
    if err!=nil{
        log.Println(err)
        return resp, err
    }
    return resp, err
}

Который при вызове должен дать:

map[proxy: keypoololdest:1.327368259e+09 blocks:45385 keypoolsize:101 connections:11 version:50200 difficulty:8.88353262 generate:false hashespersec:0 paytxfee:0 balance:0 genproclimit:-1 testnet:true errors:]

Но при вызове GAE функция, похоже, вызывает ошибку. Какая часть кода может работать на dev_appserver, но не работать на GAE?


person ThePiachu    schedule 31.01.2012    source источник


Ответы (1)


Вы должны использовать urlfetch.Transport для выполнения HTTP-вызовов в рабочей среде, как описано в urlfetch. документация.

Вместо выполнения:

resp, err := http.Post(address,
    "application/json", strings.NewReader(string(data)))

Вы должны делать:

client := urlfetch.Client(context)
resp, error := client.Post(address,
    "application/json", strings.NewReader(string(data)))

Как видно из реализации, urlfetch.Client — это просто ярлык для создания http.Client, который использует urlfetch.Transport.

person proppy    schedule 31.01.2012
comment
Хм, client.Post, похоже, выдает ошибку API error 1 (urlfetch: INVALID_URL): ApplicationError: 2 (8, «имя узла или имя сервера предоставлено или неизвестно») - person ThePiachu; 31.01.2012
comment
Каково значение address? - person proppy; 31.01.2012
comment
Он имеет формат user:[email protected]:18332, который работал для http.Post. - person ThePiachu; 01.02.2012
comment
Я считаю, что urlfetch.Transport не анализирует аутентификацию в URL-адресе, вместо этого вы должны использовать заголовок Authorization:, см. stackoverflow.com/questions/1341081/ - person proppy; 01.02.2012
comment
Думаю, в этом была проблема. Приходилось делать http.Request, потом ставить базовую авторизацию, и только потом выполнять с client.Do. Не знаю, где установить для bodyType значение application/json, но, похоже, он работает и без этого, по крайней мере, на сервере разработки. - person ThePiachu; 01.02.2012
comment
Протестировал на gae, не работает из-за самовыданного сертификата. Пришлось изменить client.Do, чтобы сначала получить &urlfetch.Transport, затем установить для параметра AllowInvalidServerCertificate значение true и только затем вызвать transport.RoundTrip(req). Только тогда он работал нормально на dev и gae. Спасибо за помощь, думаю, я скоро загружу свой окончательный код на GitHub. - person ThePiachu; 01.02.2012