TEST(HttpRequest, get_method) { ASSERT_EQ( HttpRequest(HttpRequest::Method::GET, "/").get_method(), HttpRequest::Method::GET ); ASSERT_EQ( HttpRequest(HttpRequest::Method::PUT, "/").get_method(), HttpRequest::Method::PUT ); }
int Service::HttpRequest( const string http_method, const string url ) { vector<string> custom_headers = vector<string>(); PostData post_data; return HttpRequest(http_method, url, custom_headers, post_data,this); }
bool CetonStreamHandler::TuneVChannel(const QString &vchannel) { if ((vchannel != "0") && (_last_vchannel != "0")) ClearProgramNumber(); LOG(VB_RECORD, LOG_INFO, LOC + QString("TuneVChannel(%1)").arg(vchannel)); _last_vchannel = vchannel; QUrl params; params.addQueryItem("instance_id", QString::number(_tuner)); params.addQueryItem("channel", vchannel); QString response; uint status; bool result = HttpRequest( "POST", "/channel_request.cgi", params, response, status); if (!result) { LOG(VB_RECORD, LOG_ERR, LOC + QString("TuneVChannel() - HTTP status = %1 - response = %2") .arg(status).arg(response)); } return result; }
bool CetonStreamHandler::TuneProgram(uint program) { LOG(VB_RECORD, LOG_INFO, LOC + QString("TuneProgram(%1)").arg(program)); QStringList program_list = GetProgramList(); if (!program_list.contains(QString::number(program))) { LOG(VB_RECORD, LOG_ERR, LOC + QString("TuneProgram(%1) - Requested program not in the program list").arg(program)); return false; }; _last_program = program; QUrl params; params.addQueryItem("instance_id", QString::number(_tuner)); params.addQueryItem("program", QString::number(program)); QString response; uint status; bool result = HttpRequest( "POST", "/program_request.cgi", params, response, status); if (!result) { LOG(VB_RECORD, LOG_ERR, LOC + QString("TuneProgram() - HTTP status = %1 - response = %2") .arg(status).arg(response)); } return result; }
bool CetonStreamHandler::PerformTuneVChannel(const QString &vchannel) { LOG(VB_RECORD, LOG_INFO, LOC + QString("PerformTuneVChannel(%1)") .arg(vchannel)); #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) QUrl params; #else QUrlQuery params; #endif params.addQueryItem("instance_id", QString::number(_tuner)); params.addQueryItem("channel", vchannel); QString response; uint status; bool result = HttpRequest( "POST", "/channel_request.cgi", params, response, status); if (!result) { LOG(VB_GENERAL, LOG_ERR, LOC + QString("PerformTuneVChannel() - HTTP status = %1 - response = %2") .arg(status).arg(response)); } return result; }
QString CetonStreamHandler::GetVar( const QString §ion, const QString &variable) const { QString loc = LOC + QString("DoGetVar(%1,%2,%3,%4) - ") .arg(_ip_address).arg(_tuner).arg(section,variable); QUrl params; params.addQueryItem("i", QString::number(_tuner)); params.addQueryItem("s", section); params.addQueryItem("v", variable); QString response; uint status; if (!HttpRequest("GET", "/get_var.json", params, response, status)) { LOG(VB_RECORD, LOG_ERR, loc + QString("HttpRequest failed - %1").arg(response)); return QString(); } QRegExp regex("^\\{ \"?result\"?: \"(.*)\" \\}$"); if (regex.indexIn(response) == -1) { LOG(VB_RECORD, LOG_ERR, loc + QString("unexpected http response: -->%1<--").arg(response)); return QString(); } QString result = regex.cap(1); LOG(VB_RECORD, LOG_DEBUG, loc + QString("got: -->%1<--").arg(result)); return result; }
QStringList CetonStreamHandler::GetProgramList() { QString loc = LOC + QString("CetonHTTP: DoGetProgramList(%1,%2) - ") .arg(_ip_address).arg(_tuner); #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) QUrl params; #else QUrlQuery params; #endif params.addQueryItem("i", QString::number(_tuner)); QString response; uint status; if (!HttpRequest("GET", "/get_pat.json", params, response, status)) { LOG(VB_GENERAL, LOG_ERR, loc + QString("HttpRequest failed - %1").arg(response)); return QStringList(); } QRegExp regex( "^\\{ \"?length\"?: \\d+(, \"?results\"?: \\[ (.*) \\])? \\}$"); if (regex.indexIn(response) == -1) { LOG(VB_GENERAL, LOG_ERR, loc + QString("returned unexpected output: -->%1<--") .arg(response)); return QStringList(); } LOG(VB_RECORD, LOG_DEBUG, loc + QString("got: -->%1<--").arg(regex.cap(2))); return regex.cap(2).split(", "); }
HttpRequest HttpRequest::Builder::build() const { const HttpHeader header = m_header.build(); if (header.getRequestType() == HttpHeader::eRequestType::HTTP_REQUEST_GET) { ASSERT(m_body.size() == 0); } return HttpRequest(header, m_body); }
// 发送扣费记录 void CDlgAutoRegister::SendConsumeRecord( ConsumeNode& node ) { static const LONG CodePage_GB2312 = 936; // 简体中文 (GB2312) static const LONG WinHttpRequestOption_URLCodePage = 2; CWinHttpRequest HttpRequest(FALSE); try { HttpRequest.Create(); HttpRequest.SetOption(WinHttpRequestOption_URLCodePage, COleVariant(CodePage_GB2312)); HttpRequest.SetTimeouts(5000, 5000, 10000, 1000 * 15); CString strUrlMain = _T("http://"); strUrlMain += CNetBarConfig::GetInstance()->GetMainCenterIP(); strUrlMain.AppendFormat(_T(":%d"), CNetBarConfig::GetInstance()->GetMainCenterPort()); strUrlMain += _T("/netbar/interface/Consume.jsp"); strUrlMain.AppendFormat(_T("?pwd=%s"),_T("netbarneibushiyong")); strUrlMain.AppendFormat(_T("&submitTime=%s"), CIBAHelpper::FormatTime(COleDateTime::GetCurrentTime())); strUrlMain.AppendFormat(_T("&netBarId=%d"),CNetBarConfig::GetInstance()->GetNetBarId()); strUrlMain.AppendFormat(_T("&refNo=%d"), GetRandomRefNo()); strUrlMain.AppendFormat(_T("&serialNo=%d"), CIBAConfig::GetInstance()->GetLocalSerialNo()); strUrlMain.AppendFormat(_T("&memberId=%d"), node.nMemberId); strUrlMain.AppendFormat(_T("&checkinTime=%s"), node.checkInTime); strUrlMain.AppendFormat(_T("&checkoutTime=%s"), node.checkOutTime); strUrlMain.AppendFormat(_T("&classId=%d"), GetRandomClassID()); strUrlMain.AppendFormat(_T("&pcClass=%d"), GetPCClassID()); strUrlMain.AppendFormat(_T("&termId=%s"), GetRandomTermID()); strUrlMain.AppendFormat(_T("&amount=%d"), node.nAmount); strUrlMain.AppendFormat(_T("&timeConsume=%d"), node.nTimeConsume); strUrlMain.Replace(_T(" "), _T("%20")); GXX_TRACE(_T("扣消费记录的请求: %s"), strUrlMain.GetString()); HttpRequest.Open(strUrlMain.GetString()); HttpRequest.Send(); DeRegisterNode deRegNode; deRegNode.OldDeRegisterTime = node.OleCheckOutTime + COleDateTimeSpan(0, 0, 5, 0); // 下机后5分钟退款 deRegNode.nMemberId = node.nMemberId; _tcscpy(deRegNode.idNumber, node.idNumber); _tcscpy(deRegNode.name, node.name); deRegNode.bInvalid = 0; m_cs.Lock(); m_arrDeRegisterNode.push_back(deRegNode); m_cs.Unlock(); GXX_TRACE(_T("Response: %s"), HttpRequest.GetResponseText()); } catch(...) { } }
//无参数 比如GET DELETE int Service::HttpRequest( const string http_method, const string url ) { m_resp_buffer=""; m_resp_header=""; vector<string> custom_headers = vector<string>(); return HttpRequest(http_method, url, custom_headers, NULL,NULL,this); }
HttpRequest * HttpRequest::CreateRequest(const wchar_t * target, Method method, HttpRequestStatusListener * listener) { HttpRequest * req = PNEW HttpRequest(target, method, listener); req->Hold(); // One hold for TaskRunner() req->m_task = task_create(NULL, 0, TaskRunner, req, NULL, 0); return req; // Leave held. Caller should release // the request. }
static Status blockchainPostTx(DataSlice tx) { std::string body = "tx=" + base16Encode(tx); if (isTestnet()) return ABC_ERROR(ABC_CC_Error, "No blockchain.info testnet"); HttpReply reply; ABC_CHECK(HttpRequest(). header("Content-Type", "application/x-www-form-urlencoded"). post(reply, "https://blockchain.info/pushtx", body)); ABC_CHECK(reply.codeOk()); return Status(); }
//有参数 比如POST PUT int Service::HttpRequest( const string http_method, const string url, const char *data,long datalen,string filename, int postion,int totallen) { m_resp_buffer=""; m_resp_header=""; vector<string> custom_headers = vector<string>(); if ( http_method == "POST" ) { PostData post_data; post_data.data=data; post_data.datalen=datalen; post_data.filename=filename; //FILENAME已经无效了。原本用来上传一个文件 return HttpRequest(http_method, url, custom_headers, &post_data, NULL,this); } if ( http_method == "PUT" ) { PutData putData; //可以一段段的上传文件 putData.data=data; //数据 putData.datalen=datalen; //数据大小 putData.postion=postion; //当前数据在文件中的起始位置 putData.totallen=totallen; //文件总大小 return HttpRequest(http_method, url, custom_headers, NULL, &putData,this); } //其他无参 return HttpRequest(http_method, url, custom_headers, NULL,NULL,this); }
static Status insightPostTx(DataSlice tx) { std::string body = "rawtx=" + base16Encode(tx); const char *url = isTestnet() ? "https://test-insight.bitpay.com/api/tx/send": "https://insight.bitpay.com/api/tx/send"; HttpReply reply; ABC_CHECK(HttpRequest(). post(reply, url, body)); ABC_CHECK(reply.codeOk()); return Status(); }
bool CetonStreamHandler::TuneFrequency( uint frequency, const QString &modulation) { LOG(VB_RECORD, LOG_INFO, LOC + QString("TuneFrequency(%1, %2)") .arg(frequency).arg(modulation)); if (frequency >= 100000000) frequency /= 1000; QString modulation_id = (modulation == "qam_256") ? "2" : (modulation == "qam_64") ? "0" : (modulation == "ntsc-m") ? "4" : (modulation == "8vsb") ? "6" : ""; if (modulation_id == "") return false; _last_frequency = frequency; _last_modulation = modulation; #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) QUrl params; #else QUrlQuery params; #endif params.addQueryItem("instance_id", QString::number(_tuner)); params.addQueryItem("frequency", QString::number(frequency)); params.addQueryItem("modulation",modulation_id); params.addQueryItem("tuner","1"); params.addQueryItem("demod","1"); params.addQueryItem("rst_chnl","0"); params.addQueryItem("force_tune","0"); QString response; uint status; bool result = HttpRequest( "POST", "/tune_request.cgi", params, response, status); if (!result) { LOG(VB_GENERAL, LOG_ERR, LOC + QString("TuneFrequency() - HTTP status = %1 - response = %2") .arg(status).arg(response)); } return result; }
bool HttpParser::completeRequest() { Finally f([this]() { request_ = HttpRequest(); }); switch(parser_.method) { #define _(x) case HTTP_##x: request_.method_ = HttpRequest::x; break _(GET); _(HEAD); _(POST); #undef _ default: request_.method_ = HttpRequest::OTHER; } if(parser_.http_minor != 0) // treat as HTTP 1.1 { request_.http11_ = true; } request_.upgrade_ = !!parser_.upgrade; request_.keepAlive_ = !!http_should_keep_alive(&parser_); if(!parseRequestTarget(request_.rawTarget_, request_.target_, request_.queries_)) { return false; } try { // TODO: Content-Type parameters (charset, ...) if(parser_.method == HttpRequest::POST && boost::iequals(request_.headers_.at("Content-Type"), "application/x-www-form-urlencoded")) { if(!parseQueryString(request_.rawBody_, request_.queries_)) { return false; } } } catch(const std::out_of_range &) { } return currentCallback_(request_); }
void CheckThread(const char *url, const char *post) { std::vector<char> buffer; if (HttpRequest(buffer, url, post)) { const char* content = &buffer[0]; try{ std::wistringstream stream; std::wstring_convert<std::codecvt_utf8<wchar_t>> conv; std::wstring json_str = conv.from_bytes(content, content + buffer.size()); stream.str(json_str); boost::property_tree::wptree updater; boost::property_tree::json_parser::read_json(stream, updater); } catch (std::exception e) { //OutputDebugStringA(e.what()); } } }
/** Process the work for the sockets. @param [in] pWebServer The web server control structure address. @param [in] SocketFD The socket's file descriptor to add to the list. @param [in] events everts is a bitmask of the work to be done @param [in] pPort The address of a WSDT_PORT structure @retval EFI_SUCCESS The operation was successful @retval EFI_DEVICE_ERROR Error, close the port **/ EFI_STATUS PortWork ( IN DT_WEB_SERVER * pWebServer, IN int SocketFD, IN INTN events, IN WSDT_PORT * pPort ) { BOOLEAN bDone; size_t LengthInBytes; int NewSocket; EFI_STATUS OpStatus; struct sockaddr_in6 RemoteAddress; socklen_t RemoteAddressLength; EFI_STATUS Status; DEBUG (( DEBUG_PORT_WORK, "Entering PortWork\r\n" )); // // Assume success // OpStatus = EFI_SUCCESS; // // Handle input events // if ( 0 != ( events & POLLRDNORM )) { // // Determine if this is a connection attempt // if (( SocketFD == pWebServer->HttpListenPort ) || ( SocketFD == pWebServer->HttpListenPort6 )) { // // Handle connection attempts // Accepts arrive as read events // RemoteAddressLength = sizeof ( RemoteAddress ); NewSocket = accept ( SocketFD, (struct sockaddr *)&RemoteAddress, &RemoteAddressLength ); if ( -1 != NewSocket ) { if ( 0 != NewSocket ) { // // Add this port to the list monitored by the web server // Status = PortAdd ( pWebServer, NewSocket ); if ( EFI_ERROR ( Status )) { DEBUG (( DEBUG_ERROR, "ERROR - Failed to add the port 0x%08x, Status: %r\r\n", NewSocket, Status )); // // Done with the new socket // close ( NewSocket ); } } else { DEBUG (( DEBUG_ERROR, "ERROR - Socket not available!\r\n" )); } // // Leave the listen port open // } else { // // Listen port error // Close the listen port by returning error status // OpStatus = EFI_DEVICE_ERROR; DEBUG (( DEBUG_ERROR, "ERROR - Failed to accept new connection, errno: 0x%08x\r\n", errno )); } } else { // // Handle the data received event // if ( 0 == pPort->RequestLength ) { // // Receive the page request // pPort->RequestLength = recv ( SocketFD, &pPort->Request[0], DIM ( pPort->Request ), 0 ); if ( -1 == pPort->RequestLength ) { // // Receive error detected // Close the port // OpStatus = EFI_DEVICE_ERROR; } else { DEBUG (( DEBUG_REQUEST, "0x%08x: Socket - Received %d bytes of HTTP request\r\n", SocketFD, pPort->RequestLength )); // // Process the request // OpStatus = HttpRequest ( SocketFD, pPort, &bDone ); if ( bDone ) { // // Notify the upper layer to close the socket // OpStatus = EFI_DEVICE_ERROR; } } } else { // // Receive the file data // LengthInBytes = recv ( SocketFD, &pPort->RxBuffer[0], DIM ( pPort->RxBuffer ), 0 ); if ( -1 == LengthInBytes ) { // // Receive error detected // Close the port // OpStatus = EFI_DEVICE_ERROR; } else { DEBUG (( DEBUG_REQUEST, "0x%08x: Socket - Received %d bytes of file data\r\n", SocketFD, LengthInBytes )); // // TODO: Process the file data // } } } } // // Handle the close event // if ( 0 != ( events & POLLHUP )) { // // Close the port // OpStatus = EFI_DEVICE_ERROR; } // // Return the operation status // DEBUG (( DEBUG_PORT_WORK, "Exiting PortWork, Status: %r\r\n", OpStatus )); return OpStatus; }
void HttpServer::internalHttpHandler(websocketpp::connection_hdl hdl) { HttpSession *session = new HttpSession(&server_, hdl); HttpRequest(session); delete session; }
int main(int argc, const char * argv[]) { HttpClient client; // GET Methodのテスト { auto time_point = std::chrono::system_clock::now(); HttpTransactionHandle handles[10]; std::atomic<int> val(0); for( int i=0; i<ARRAY_SIZEOF(handles); ++i ) { auto thread = std::thread( [&val, &handles, &client, i](){ handles[i] = client.CreateRequest( HttpRequest( "http://google.co.jp", HttpRequest::GET ), [&val]( const HttpTransaction& transaction, const char* data, size_t dataSize ){ if( transaction.IsOk() ) { std::atomic_fetch_add(&val, 1); std::cout << "val : " << val << std::endl; std::cout << data << std::endl; } else { std::cout << "error" << std::endl; } }, false ); } ); thread.detach(); } while( true ) { client.Update(); bool allCompleted = true; for( int i=0; i<ARRAY_SIZEOF(handles); ++i ) { if( !client.IsCompleted( handles[i] ) ) { allCompleted = false; } } if( allCompleted ) { break; } } for( int i=0; i<ARRAY_SIZEOF(handles); ++i ) { client.ReleaseTransaction( handles[i] ); } auto duration = std::chrono::system_clock::now() - time_point ; std::cout << "google.co.jpにGETするのにかかった時間" << duration.count() / 1000.0 / 1000.0 << std::endl ; } // POSTメソッドのテスト。google.co.jpはpostには対応していないのでエラーが返ってくる { auto time_point = std::chrono::system_clock::now(); HttpRequest request( "http://google.co.jp", HttpRequest::POST ); request.SetPostField("name=hoge"); request.SetTimeout(1.0f); auto handle = client.CreateRequest( request, []( const HttpTransaction& transaction, const char* data, size_t dataSize ){ if( transaction.IsOk() ) { std::cout << data << std::endl; } else if( transaction.IsTimeout() ) { std::cout << "timeout..." << std::endl; } }); while( !client.IsCompleted(handle) ) { client.Update(); } auto duration = std::chrono::system_clock::now() - time_point ; std::cout << "google.co.jpにPOSTするのにかかった時間" << duration.count() / 1000.0 / 1000.0 << std::endl ; } return 0; }
void LevelDatabaseDownloadThread::run() { if(errorNumber == 100) return; dSprintf(url, UrlLength, (HttpRequest::LevelDatabaseBaseUrl + LevelRequest).c_str(), mLevelId.c_str()); HttpRequest req(url); if(!req.send()) { dSprintf(url, UrlLength, "!!! Error connecting to server"); errorNumber = 1; return; } if(req.getResponseCode() != HttpRequest::OK) { dSprintf(url, UrlLength, "!!! Server returned an error: %d", req.getResponseCode()); errorNumber = 1; return; } string levelCode = req.getResponseBody(); string filePath = joindir(levelDir, levelFileName); if(writeFile(filePath, levelCode)) { // Success } else // File writing went bad { dSprintf(url, UrlLength, "!!! Could not write to %s", levelFileName.c_str()); errorNumber = 1; return; } dSprintf(url, UrlLength, (HttpRequest::LevelDatabaseBaseUrl + LevelgenRequest).c_str(), mLevelId.c_str()); req = HttpRequest(url); if(!req.send()) { dSprintf(url, UrlLength, "!!! Error connecting to server", levelFileName.c_str()); errorNumber = 2; return; } if(req.getResponseCode() != HttpRequest::OK) { dSprintf(url, UrlLength, "!!! Server returned an error: %d", req.getResponseCode()); errorNumber = 2; return; } string levelgenCode = req.getResponseBody(); // no data is sent if the level has no levelgen if(levelgenCode.length() > 0) { // the leveldb prepends a lua comment with the target filename, and here we parse it int startIndex = 3; // the length of "-- " int breakIndex = levelgenCode.find_first_of("\r\n"); string levelgenFileName = levelgenCode.substr(startIndex, breakIndex - startIndex); // trim the filename line before writing levelgenCode = levelgenCode.substr(breakIndex + 2, levelgenCode.length()); filePath = joindir(levelDir, levelgenFileName); if(writeFile(filePath, levelgenCode)) { // Success } else { dSprintf(url, UrlLength, "!!! Server returned an error: %d", req.getResponseCode()); errorNumber = 2; return; } } }
TEST(HttpRequest, constructor) { HttpRequest(HttpRequest::Method::GET, "/"); HttpRequest(HttpRequest::Method::GET, "/", &Buffer::copy("test")); HttpRequest(HttpRequest::Method::GET, "/", &Buffer::copy("test")); HttpRequest(HttpRequest::Method::GET, "/", &Buffer::copy("test"), 1); }
UINT DCGetMyIpMain(DDNS_CLIENT *c, bool ipv6, char *dst, UINT dst_size, bool use_ssl, char *replace_v6) { char *url; char url2[MAX_SIZE]; UINT ret = ERR_INTERNAL_ERROR; URL_DATA data; BUF *recv; BUF *cert_hash; // Validate arguments if (dst == NULL || c == NULL) { return ERR_INTERNAL_ERROR; } if (ipv6 == false) { url = DDNS_URL2_V4_GLOBAL; if (IsUseAlternativeHostname()) { url = DDNS_URL2_V4_ALT; } } else { url = DDNS_URL2_V6_GLOBAL; if (IsUseAlternativeHostname()) { url = DDNS_URL2_V6_ALT; } if (replace_v6) { url = replace_v6; } } Format(url2, sizeof(url2), "%s?v=%I64u", url, Rand64()); if (use_ssl) { ReplaceStr(url2, sizeof(url2), url2, "http://", "https://"); } if (ParseUrl(&data, url2, false, NULL) == false) { return ERR_INTERNAL_ERROR; } cert_hash = StrToBin(DDNS_CERT_HASH); recv = HttpRequest(&data, (ipv6 ? NULL : &c->InternetSetting), DDNS_CONNECT_TIMEOUT, DDNS_COMM_TIMEOUT, &ret, false, NULL, NULL, NULL, ((cert_hash != NULL && cert_hash->Size == SHA1_SIZE) ? cert_hash->Buf : NULL)); FreeBuf(cert_hash); if (recv != NULL) { char *str = ZeroMalloc(recv->Size + 1); Copy(str, recv->Buf, recv->Size); if (StartWith(str, "IP=") == false) { ret = ERR_PROTOCOL_ERROR; } else { StrCpy(dst, dst_size, str + 3); ret = ERR_NO_ERROR; } Free(str); FreeBuf(recv); } if (IsUseAlternativeHostname() == false) { if (ret == ERR_CONNECT_FAILED) { if (ipv6 && replace_v6 == NULL && use_ssl == false) { UINT type = DetectFletsType(); if (type & FLETS_DETECT_TYPE_EAST_BFLETS_PRIVATE && ret != ERR_NO_ERROR) { ret = DCGetMyIpMain(c, ipv6, dst, dst_size, use_ssl, DDNS_REPLACE_URL2_FOR_EAST_BFLETS); } if (type & FLETS_DETECT_TYPE_EAST_NGN_PRIVATE && ret != ERR_NO_ERROR) { ret = DCGetMyIpMain(c, ipv6, dst, dst_size, use_ssl, DDNS_REPLACE_URL2_FOR_EAST_NGN); } if (type & FLETS_DETECT_TYPE_WEST_NGN_PRIVATE && ret != ERR_NO_ERROR) { ret = DCGetMyIpMain(c, ipv6, dst, dst_size, use_ssl, DDNS_REPLACE_URL2_FOR_WEST_NGN); } } } } return ret; }
TEST(HttpRequest, get_uri) { yield::uri::Uri uri("/test"); ASSERT_EQ(HttpRequest(HttpRequest::Method::GET, uri).get_uri(), uri); }
void Bing::sendRequest() { // Recupère la page web de la requette Bing et la met dans m_DOM HttpRequest("http://www.bing.com/search?q=\""+m_text+"\""); }
/* piano wrapper: prepare/execute http request and pass result back to * libpiano (updates data structures) * @return 1 on success, 0 otherwise */ int BarUiPianoCall (BarApp_t * const app, PianoRequestType_t type, void *data, PianoReturn_t *pRet) { PianoRequest_t req; memset (&req, 0, sizeof (req)); /* repeat as long as there are http requests to do */ do { req.data = data; *pRet = PianoRequest (&app->ph, &req, type); if (*pRet != PIANO_RET_OK) { BarUiMsg (&app->settings, MSG_NONE, "Error: %s\n", PianoErrorToStr (*pRet)); PianoDestroyRequest (&req); return 0; } if (!HttpRequest(app->http2, &req)) { BarUiMsg(&app->settings, MSG_NONE, "Network error: %s\n", HttpGetError(app->http2)); if (req.responseData != NULL) { free(req.responseData); } PianoDestroyRequest(&req); return 0; } *pRet = PianoResponse (&app->ph, &req); if (*pRet != PIANO_RET_CONTINUE_REQUEST) { /* checking for request type avoids infinite loops */ if (*pRet == PIANO_RET_P_INVALID_AUTH_TOKEN && type != PIANO_REQUEST_LOGIN) { /* reauthenticate */ PianoReturn_t authpRet; PianoRequestDataLogin_t reqData; reqData.user = app->settings.username; reqData.password = app->settings.password; reqData.step = 0; BarUiMsg (&app->settings, MSG_NONE, "Reauthentication required... "); if (!BarUiPianoCall (app, PIANO_REQUEST_LOGIN, &reqData, &authpRet)) { *pRet = authpRet; if (req.responseData != NULL) { free (req.responseData); } PianoDestroyRequest (&req); return 0; } else { /* try again */ *pRet = PIANO_RET_CONTINUE_REQUEST; BarUiMsg (&app->settings, MSG_INFO, "Trying again... "); } } else if (*pRet != PIANO_RET_OK) { BarUiMsg (&app->settings, MSG_NONE, "Error: %s\n", PianoErrorToStr (*pRet)); if (req.responseData != NULL) { free (req.responseData); } PianoDestroyRequest (&req); return 0; } else { BarUiMsg (&app->settings, MSG_NONE, "Ok.\n"); } } /* we can destroy the request at this point, even when this call needs * more than one http request. persistent data (step counter, e.g.) is * stored in req.data */ if (req.responseData != NULL) { free (req.responseData); } PianoDestroyRequest (&req); } while (*pRet == PIANO_RET_CONTINUE_REQUEST); return 1; }