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); }
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"); } }
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; }
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(); } }
CHttpResponse * CWebApplication::createHttpResponse() { CHttpResponse * response = new CHttpResponse(this); response->init(); return response; }
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); }