char *http_async_req_stop(void *ctx, int *ret, int *len) { struct http_ctx *cx = ctx; char *rxd; if(cx->state != HTS_DONE) while(!http_async_req_status(ctx)) ; if(cx->host) { free(cx->host); cx->host = NULL; } if(cx->path) { free(cx->path); cx->path = NULL; } if(cx->txd) { free(cx->txd); cx->txd = NULL; cx->txdl = 0; } if(cx->hbuf) { free(cx->hbuf); cx->hbuf = NULL; } if(cx->thdr) { free(cx->thdr); cx->thdr = NULL; cx->thlen = 0; } if(ret) *ret = cx->ret; if(len) *len = cx->rptr; if(cx->rbuf) cx->rbuf[cx->rptr] = 0; rxd = cx->rbuf; cx->rbuf = NULL; cx->rlen = 0; cx->rptr = 0; cx->contlen = 0; if(!cx->keep) http_async_req_close(ctx); else if(cx->cclose) { PCLOSE(cx->fd); cx->fd = PERROR; if(cx->fdhost) { free(cx->fdhost); cx->fdhost = NULL; } cx->state = HTS_STRT; } else cx->state = HTS_IDLE; return rxd; }
RequestBroker::ProcessResponse WebRequest::Process(RequestBroker & rb) { if(HTTPContext) { if(http_async_req_status(HTTPContext)) { char * data; int status, data_size; data = http_async_req_stop(HTTPContext, &status, &data_size); if (status == 200 && data) { void * resultObject = new std::vector<unsigned char>(data, data+data_size); if(resultObject) { this->ResultObject = resultObject; rb.requestComplete(this); free(data); return RequestBroker::Finished; } else { std::cout << typeid(*this).name() << " Request for " << URL << " could not be parsed: " << data << std::endl; free(data); return RequestBroker::Failed; } } else { //#ifdef DEBUG std::cout << typeid(*this).name() << " Request for " << URL << " failed with status " << status << std::endl; //#endif if(data) free(data); return RequestBroker::Failed; } } } else { std::cout << typeid(*this).name() << " New Request for " << URL << std::endl; if(Post) { char ** postNames = new char*[PostData.size() + 1]; char ** postData = new char*[PostData.size()]; int * postLength = new int[PostData.size()]; int i = 0; std::map<std::string, std::string>::iterator iter = PostData.begin(); while(iter != PostData.end()) { std::string name = iter->first; std::string data = iter->second; char * cName = new char[name.length() + 1]; char * cData = new char[data.length() + 1]; std::strcpy(cName, name.c_str()); std::strcpy(cData, data.c_str()); postNames[i] = cName; postData[i] = cData; postLength[i] = data.length(); i++; iter++; } postNames[i] = NULL; if(Client::Ref().GetAuthUser().ID) { std::cout << typeid(*this).name() << " Authenticated " << std::endl; User user = Client::Ref().GetAuthUser(); char userName[12]; char *userSession = new char[user.SessionID.length() + 1]; std::strcpy(userName, format::NumberToString<int>(user.ID).c_str()); std::strcpy(userSession, user.SessionID.c_str()); HTTPContext = http_multipart_post_async((char*)URL.c_str(), postNames, postData, postLength, userName, NULL, userSession); delete userSession; } else { HTTPContext = http_multipart_post_async((char*)URL.c_str(), postNames, postData, postLength, NULL, NULL, NULL); } } else { HTTPContext = http_async_req_start(NULL, (char *)URL.c_str(), NULL, 0, 0); if(Client::Ref().GetAuthUser().ID) { User user = Client::Ref().GetAuthUser(); char userName[12]; char *userSession = new char[user.SessionID.length() + 1]; std::strcpy(userName, format::NumberToString<int>(user.ID).c_str()); std::strcpy(userSession, user.SessionID.c_str()); http_auth_headers(HTTPContext, userName, NULL, userSession); delete[] userSession; } } } return RequestBroker::OK; }
RequestBroker::ProcessResponse ImageRequest::Process(RequestBroker & rb) { VideoBuffer * image = NULL; //Have a look at the thumbnail cache for(std::deque<std::pair<std::string, VideoBuffer*> >::iterator iter = rb.imageCache.begin(), end = rb.imageCache.end(); iter != end; ++iter) { if((*iter).first == URL) { image = (*iter).second; #ifdef DEBUG std::cout << typeid(*this).name() << " " << URL << " found in cache" << std::endl; #endif } } if(!image) { if(HTTPContext) { if(http_async_req_status(HTTPContext)) { pixel * imageData; char * data; int status, data_size, imgw, imgh; data = http_async_req_stop(HTTPContext, &status, &data_size); if (status == 200 && data) { imageData = Graphics::ptif_unpack(data, data_size, &imgw, &imgh); free(data); if(imageData) { //Success! image = new VideoBuffer(imageData, imgw, imgh); free(imageData); } else { //Error thumbnail image = new VideoBuffer(32, 32); image->SetCharacter(14, 14, 'x', 255, 255, 255, 255); } if(rb.imageCache.size() >= THUMB_CACHE_SIZE) { //Remove unnecessary from thumbnail cache delete rb.imageCache.front().second; rb.imageCache.pop_front(); } rb.imageCache.push_back(std::pair<std::string, VideoBuffer*>(URL, image)); } else { #ifdef DEBUG std::cout << typeid(*this).name() << " Request for " << URL << " failed with status " << status << std::endl; #endif free(data); return RequestBroker::Failed; } } } else { //Check for ongoing requests for(std::vector<Request*>::iterator iter = rb.activeRequests.begin(), end = rb.activeRequests.end(); iter != end; ++iter) { if((*iter)->Type != Request::Image) continue; ImageRequest * otherReq = (ImageRequest*)(*iter); if(otherReq->URL == URL && otherReq != this) { #ifdef DEBUG std::cout << typeid(*this).name() << " Request for " << URL << " found, appending." << std::endl; #endif //Add the current listener to the item already being requested (*iter)->Children.push_back(this); return RequestBroker::Duplicate; } } //If it's not already being requested, request it #ifdef DEBUG std::cout << typeid(*this).name() << " Creating new request for " << URL << std::endl; #endif HTTPContext = http_async_req_start(NULL, (char *)URL.c_str(), NULL, 0, 0); RequestTime = time(NULL); } } if(image) { //Create a copy, to seperate from the cache std::vector<Request *> children(Children.begin(), Children.end()); Children.clear(); VideoBuffer * myVB = new VideoBuffer(*image); myVB->Resize(Width, Height, true); ResultObject = (void*)myVB; rb.requestComplete(this); for(std::vector<Request*>::iterator childIter = children.begin(), childEnd = children.end(); childIter != childEnd; ++childIter) { if((*childIter)->Type == Request::Image) { ImageRequest * childReq = (ImageRequest*)*childIter; VideoBuffer * tempImage = new VideoBuffer(*image); tempImage->Resize(childReq->Width, childReq->Height, true); childReq->ResultObject = (void*)tempImage; rb.requestComplete(*childIter); } } return RequestBroker::Finished; } return RequestBroker::OK; }
void update_notify_ui_process(pixel *vid_buf, int mb, int mbq, int mx, int my) { if (version_check==1 && !version_check_http) version_check_http = http_async_req_start(NULL, "http://" SERVER "/Update.api?Action=CheckVersion", NULL, 0, 0); if (version_check_http) { if (!version_check_http_counter && http_async_req_status(version_check_http)) { int http_ret; char *ver_data; ver_data = http_async_req_stop(version_check_http, &http_ret, NULL); if (http_ret==200 && ver_data) { #ifdef BETA if (sscanf(ver_data, "%d.%d.%d", &version_check_major, &version_check_minor, &version_check_isbeta)==3) if (version_check_major>SAVE_VERSION || (version_check_major==SAVE_VERSION && version_check_minor>MINOR_VERSION) || (version_check_major==SAVE_VERSION && version_check_isbeta == 0)) version_check = 2; #else if (sscanf(ver_data, "%d.%d", &version_check_major, &version_check_minor)==2) if (version_check_major>SAVE_VERSION || (version_check_major==SAVE_VERSION && version_check_minor>MINOR_VERSION)) version_check = 2; #endif #ifdef BETA if (version_check_isbeta) old_ver_len = textwidth(old_ver_msg_beta); else old_ver_len = textwidth(old_ver_msg); #else old_ver_len = textwidth(old_ver_msg); #endif } if (ver_data) free(ver_data); version_check_http = NULL; } version_check_http_counter = (version_check_http_counter+1) & 15; } if (mb && !mbq && mx>=(XRES-19-old_ver_len) && mx<=(XRES-14) && my>=(YRES-22) && my<=(YRES-9) && version_check==2) { char *tmp = malloc(64); #ifdef BETA if (version_check_isbeta) { sprintf(tmp, "Your version: %d (Beta %d), new version: %d (Beta %d).", SAVE_VERSION, MINOR_VERSION, version_check_major, version_check_minor); } else { sprintf(tmp, "Your version: %d (Beta %d), new version: %d.%d.", SAVE_VERSION, MINOR_VERSION, version_check_major, version_check_minor); } #else sprintf(tmp, "Your version: %d.%d, new version: %d.%d.", SAVE_VERSION, MINOR_VERSION, version_check_major, version_check_minor); #endif if (confirm_ui(vid_buf, "Do you want to update The Powder Toy?", tmp, "Update")) { int i; free(tmp); tmp = download_ui(vid_buf, update_uri, &i); if (tmp) { save_presets(1); if (update_start(tmp, i)) { update_cleanup(); save_presets(0); error_ui(vid_buf, 0, "Update failed - try downloading a new version."); } else exit(0); } } else free(tmp); } }