示例#1
0
void CWebApplication::renderException(const CException & e)
{
	CHttpResponse * response = getResponse();
#ifdef CWS_DEBUG
	string message = e.getFullMessage();
#else
	string message = e.getMessage();
#endif
	Cws::log(message, CLogger::LEVEL_ERROR);
	response->echo(utf8_to_(message));
}
bool CHttpConnection::getTraceHeader(const CUrl &url, CHttpResponse &header, int maxforwards) {
  vector<string> vr;
  if(!getTraceHeader(url, vr, maxforwards))
    return(false);
  header.extract(vr);
  return(true);
}
bool CHttpConnection::getHeadHeader(const CUrl &url, CHttpResponse &header) {
  vector<string> vr;
  if(!getHeadHeader(url, vr))
    return(false);
  header.extract(vr);
  return(true);
}
示例#4
0
void CWebUser::loginRequired() throw (CHttpException)
{
	CWebApplication * app = dynamic_cast<CWebApplication*>(Cws::app());
	CHttpRequest * request = app->getRequest();
	CHttpResponse * response = app->getResponse();

	if (!request->getIsAjaxRequest()) {
		setReturnUrl(request->getRequestUri());
	} else if (!loginRequiredAjaxResponse.empty()) {
		response->echo(loginRequiredAjaxResponse);
		app->end();
	}

	if (!loginUrl.path.empty()) {
		string url = app->getUrlManager()->createUrl(loginUrl);
		response->redirect(url);
	} else {
		throw CHttpException(403, "Login Required");
	}
}
示例#5
0
int main(int argc, char* argv[])
{
	CHttpResponse r;

	string str;
	char* buff = strdup("HTTP/1.1 500 ( 无效索引。  )\r\nVia: 1.1 SERVER\r\nConnection: close\r\nProxy-Connection: close\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nContent-Type: text/html\r\nContent-Length: 4\r\n");
	r.Parse(buff, strlen(buff));
	assert(r.GetCode() == 500);
	assert(r.GetHeader("Via", str) && str == "1.1 SERVER");
	assert(r.GetHeader("Content-Length", str) && str == "4");
	assert(r.SetBody((char*)strdup("1234"), 4));
	assert(strncmp((char*)r.GetBodyData(), "1234", r.GetBodyLength()) == 0);
	free(buff);

	return 0;
}
示例#6
0
void CWebUser::logout(bool destroySession)
{
	if (beforeLogout()) {
		CWebApplication * app = dynamic_cast<CWebApplication*>(Cws::app());
		if (allowAutoLogin) {
			CCookieCollection cookies = app->getRequest()->getCookies();
			CHttpResponse * response = app->getResponse();
			response->removeCookie(getStateKeyPrefix());
			if (identityCookie.empty()) {
				CHttpCookie cookie = createIdentityCookie(getStateKeyPrefix());
				response->removeCookie(cookie);
			}
		}
		if (destroySession) {
			CHttpSession * session = dynamic_cast<CHttpSession*>(app->getComponent("session"));
			session->destroy();
		} else {
			clearStates();
		}
		_access = TWebUserAccessMap();
		afterLogout();
	}
}
示例#7
0
CHttpResponse * CWebApplication::createHttpResponse()
{
	CHttpResponse * response = new CHttpResponse(this);
	response->init();
	return response;
}
示例#8
0
static int OnHttpRequest(void* cls,
                         struct MHD_Connection* connection,
                         const char* url,
                         const char* method,
                         const char* version,
                         const char* upload_data,
                         size_t* upload_data_size,
                         void** ptr)
{
  if (!*ptr)
  {
    *ptr = new std::string;
    return MHD_YES;
  }

  std::string* str = (std::string*) *ptr;

  if (strcmp(method, "POST") == 0 && *upload_data_size)
  {
    *upload_data_size = 0;
    (*str) += upload_data;
    return MHD_YES;
  }

  CLog::Log(LOGDEBUG,"OnHttpRequest - enter function [url=%s][method=%s][version=%s][upload_data=%s][upload_data_size=%lu] (hsrv)",url,method,version,upload_data,*upload_data_size);

  CHttpServer* httpServer = (CHttpServer*)cls;
  if (!httpServer)
  {
    CLog::Log(LOGERROR,"OnHttpRequest - FAILED to get server context (hsrv)");
    return MHD_NO;
  }

  MAPHTTPHEADER header;
  MHD_get_connection_values(connection, MHD_HEADER_KIND, HeadersIterator, &header);

#if 0
  std::map<char*, char*>::const_iterator end = headerParams.end();
  for (std::map<char*, char*>::const_iterator it = headerParams.begin(); it != end; ++it)
  {
      std::cout << "Key: " << it->first;
      std::cout << "Value: " << it->second << '\n';
  }
#endif

  CHttpRequest httpRequest((char*) method, (char*) version, (char*) url, header, str->size(), (char*) str->c_str());
  CHttpResponse httpResponse;

  CLog::Log(LOGDEBUG,"OnHttpRequest - BEFORE HandleRequest with [method=%s][version=%s][url=%s][str=%s][strSize=%lu] (hsrv)",method,version,url,str->c_str(),str->size());
  httpServer->HandleRequest(httpRequest, httpResponse);
  CLog::Log(LOGDEBUG,"OnHttpRequest - AFTER HandleRequest with [method=%s][version=%s][url=%s][str=%s][strSize=%lu]. [IsChunked=%d] (hsrv)",method,version,url,str->c_str(),str->size(),httpResponse.IsChunked());

  struct MHD_Response* response;

  if (httpResponse.IsChunked())
  {
    CStdString deviceId = "";
    IMAPHTTPHEADER it = header.find("X-Boxee-Device-ID");
    if (it == header.end())
    {
      CLog::Log(LOGWARNING,"OnHttpRequest - FAILED to get X-Boxee-Device-ID from header for chunked request (hsrv)");
    }
    else
    {
      deviceId = it->second;
    }

    CReaderCallback* readerCls = new CReaderCallback(deviceId, CStdString(url));
    readerCls->chunkedCB = httpResponse.GetChunkedCallback();

    CLog::Log(LOGDEBUG,"OnHttpRequest - going to response_from_callback. [method=%s][version=%s][url=%s][str=%s][strSize=%lu]. [IsChunked=%d] (hsrv)",method,version,url,str->c_str(),str->size(),httpResponse.IsChunked());

    response = MHD_create_response_from_callback(MHD_SIZE_UNKNOWN, 65535, readerCallback, readerCls, NULL);

    if (MHD_add_response_header(response, "Transfer-Encoding", "chunked") == MHD_NO)
    {
      CLog::Log(LOGERROR,"OnHttpRequest - FAILED to add server to header");
      return MHD_NO;
    }
  }
  else
  {
    unsigned char* bodyPtr = &(httpResponse.GetBody()[0]);
    response = MHD_create_response_from_buffer(httpResponse.GetBody().size(), bodyPtr, MHD_RESPMEM_MUST_COPY);
  }

  if (!response)
  {
    CLog::Log(LOGERROR,"OnHttpRequest - FAILED to create response. [%s] (hsrv)",method);
    return MHD_NO;
  }

  if (MHD_add_response_header(response, "Server", httpServer->GetServerAgent().c_str()) == MHD_NO)
  {
    CLog::Log(LOGERROR,"OnHttpRequest - FAILED to add server to header");
    return MHD_NO;
  }

  std::map<std::string, std::string>::iterator it = httpResponse.GetHeader().begin();
  while (it != httpResponse.GetHeader().end())
  {
    if (MHD_add_response_header(response, it->first.c_str(), it->second.c_str()) == MHD_NO)
    {
      CLog::Log(LOGERROR,"OnHttpRequest - FAILED to add response header [%s=%s] (hsrv)", it->first.c_str(), it->second.c_str());
    }

    it++;
  }

  CLog::Log(LOGDEBUG,"OnHttpRequest - going to queue response. [code=%d][bodySize=%lu] (hsrv)",httpResponse.GetCode(), httpResponse.GetBody().size());

  int retVal = MHD_YES;
  if (MHD_queue_response(connection, httpResponse.GetCode(), response) != MHD_YES)
  {
    CLog::Log(LOGERROR,"OnHttpRequest - FAILED to queue response. [%s] (hsrv)",method);
    retVal = MHD_NO;
  }

  MHD_destroy_response(response);

  delete str;

  return retVal;
}
bool CHttpConnection::normalFileTransfer(const std::string &filename, const CHttpResponse &response) {
/*
** Datei auf lokalem Datenträger zum Schreiben öffnen
*/
  CFile file;
  if(!file.open(filename,true,true)) {
    m_lastError="FEHLER! Lokale Datei konnte nicht zum Schreiben geoeffnet werden!";
    CBTRACELN("FEHLER! Lokale Datei konnte nicht zum Schreiben geoeffnet werden!");
    return(false);
  }
  CMemory<char> buf(10000);
  unsigned int amount;
  CHugeNumber totallyRead, bufsize("10000");

/*
** Wenn Content-Length verfügbar, dann werden abgezählte
** Daten empfangen
*/
  if(response.isContenLengthAvailable()) {
    CHugeNumber length=response.getContentLength();
    CBTRACELN("Abgezaehlte Daten ("+length.getAsPointedNumber()+") werden gelesen!");
    do {
/*
** Darauf achten, dass nicht mehr Daten empfangen
** werden sollen als benötigt werden (weil read sonst
** blockiert.)
*/
      if(length>=bufsize)
        amount=m_iconn->receive(buf,10000);
      else
        amount=m_iconn->receive(buf,length.getAsUnsignedLong());

      file.writeBlock(buf,amount);
      totallyRead+=static_cast<unsigned long>(amount);
      length-=static_cast<unsigned long>(amount);
      CBTRACE("Bisher uebertragen: "+totallyRead.getAsPointedNumber()+" Bytes\r");
/*
** Keine Daten mehr empfangen, obwohl noch nicht alle Daten
** angekommen sind?
** => Fehler!
*/
      if((totallyRead==0)&&(length!=0)) {
        m_lastError="chunkedTransfer: Übertragung abgebrochen";
        CBTRACE("chunkedTransfer: Übertragung abgebrochen");
        return(false);
      }
    } while(length!=0);
  }
/*
** Wenn keine Content-Length verfügbar, dann Daten
** empfangen, bis der Server die Verbindung trennt
*/
  else {
    CBTRACELN("Daten lesen bis zum Ende!");
    do {
      amount=m_iconn->receive(buf,10000);
      file.writeBlock(buf,amount);
      totallyRead+=static_cast<unsigned long>(amount);
      CBTRACE("Bisher uebertragen: "+totallyRead.getAsPointedNumber()+" Bytes\r");
    } while(amount);
  }

  CBTRACELN("\nErfolg!");
  return(true);
}
bool CHttpConnection::getFile(const CUrl &url, const string &filename, const CHttpRequest &request) {
  CBTRACELN("\ngetFile\n-----------------------------------------------------");

/*
** Verbindung zum Server herstellen
*/
  if(!connect(url)) {
    m_lastError="Fehler bei connect";
    CBTRACELN("Fehler bei connect");
    return(false);
  }
/*
** Request senden
*/
  if(!sendRequest(request)) {
    m_lastError="Fehler bei sendRequest";
    CBTRACELN("Fehler bei sendRequest");
    return(false);
  }
/*
** Server-Response empfangen
*/
  vector<string> vresponse;
  if(!receiveResponse(vresponse)) {
    m_lastError="Fehler bei receiveResponse";
    CBTRACELN("Fehler bei receiveResponse");
    return(false);
  }
/*
** Response in ein CHttpResponse-Objekt umwandeln
*/
  bool success;
  CHttpResponse response;
  response.extract(vresponse);
  int code=response.getStatusCode();
/*
** Status zwischen 301 und 307?
** => Ressource wurde verschoben. Neue Location aus
** Response holen und getFile neu aufrufen
*/
  if((code>=301)&&(code<=307)&&(response.getLocation()!="")) {
    CBTRACELN("\nRessource verschoben. Neue Location bearbeiten...");
    disconnect();
    return(getFile(CUrl(response.getLocation()), filename));
  }
/*
** Alle Status-Codes außerhalb des 200er-Bereichs
** als Fehler betrachten
*/
  else if((response.getStatusCode()<200)||(response.getStatusCode()>=300)) {
    m_lastError=toString(response.getStatusCode())+" "+response.getStatusText();
    CBTRACELN("Server meldet Fehler");
    return(false);
  }
  else {
/*
** Je nachdem, ob Transfer an einem Stück oder
** in Chunks benötigt wird, die entsprechende
** Methode aufrufen
*/
    if(!response.isTransferChunked())
      success=normalFileTransfer(filename, response);
    else {
      success=chunkedFileTransfer(filename, response);
/*
** Hat ein Transfer in Chunks stattgefunden?
** => Hinter den Chunks nach eventuellen Entity-Headern
** Ausschau halten
*/
      if(success) {
        vresponse.clear();
        receiveResponse(vresponse);
        response.extract(vresponse,false);
      }
    }
  }
/*
** Komplette Server-Antwort im Objekt speichern
*/
  m_lastResponse=response;
  return(success);
}