예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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);
		}
}