/* Pull operation version of SendResponse. This adds one additional parameter (bodyParamsIn) that contains the parameters. This is because the parameters are added only on the the final segment of a chunk */ void CIMOperationResponseEncoder::sendResponsePull( CIMResponseMessage* response, const String& name, Boolean isImplicit, Buffer* bodyParams, Buffer* bodygiven) { PEG_METHOD_ENTER(TRC_DISPATCHER, "CIMOperationResponseEncoder::sendResponse"); PEG_TRACE((TRC_HTTP, Tracer::LEVEL4, "name = %s", (const char*)name.getCString())); if (! response) { PEG_METHOD_EXIT(); return; } Uint32 queueId = response->queueIds.top(); Boolean closeConnect = response->getCloseConnect(); PEG_TRACE(( TRC_HTTP, Tracer::LEVEL4, "CIMOperationResponseEncoder::sendResponse()- " "response->getCloseConnect() returned %d", closeConnect)); MessageQueue* queue = MessageQueue::lookup(queueId); if (!queue) { PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL1, "ERROR: non-existent queueId = %u, response not sent.", queueId)); PEG_METHOD_EXIT(); return; } HttpMethod httpMethod = response->getHttpMethod(); String& messageId = response->messageId; CIMException& cimException = response->cimException; Buffer message; // Note: the language is ALWAYS passed empty to the xml formatters because // it is HTTPConnection that needs to make the decision of whether to add // the languages to the HTTP message. ContentLanguageList contentLanguage; CIMName cimName(name); Uint32 messageIndex = response->getIndex(); Boolean isFirst = messageIndex == 0 ? true : false; Boolean isLast = response->isComplete(); Buffer bodylocal; Buffer& body = bodygiven ? *bodygiven : bodylocal; Buffer& bodyParamsBuf = bodyParams ? *bodyParams : bodylocal; // STAT_SERVEREND sets the getTotalServerTime() value in the message class STAT_SERVEREND #ifndef PEGASUS_DISABLE_PERFINST Uint64 serverTime = response->getTotalServerTime(); #else Uint64 serverTime = 0; #endif Buffer (*formatResponse)( const CIMName& iMethodName, const String& messageId, HttpMethod httpMethod, const ContentLanguageList& httpContentLanguages, const Buffer& bodyParams, const Buffer& body, Uint64 serverResponseTime, Boolean isFirst, Boolean isLast); Buffer (*formatError)( const CIMName& methodName, const String& messageId, HttpMethod httpMethod, const CIMException& cimException); if (isImplicit == false) { formatResponse = XmlWriter::formatSimpleMethodRspMessage; formatError = XmlWriter::formatSimpleMethodErrorRspMessage; } else { formatError = XmlWriter::formatSimpleIMethodErrorRspMessage; if (response->binaryResponse) { formatResponse = BinaryCodec::formatSimpleIMethodRspMessage; } else { formatResponse = XmlWriter::formatSimpleIMethodRspMessage; } } if (cimException.getCode() != CIM_ERR_SUCCESS) { HTTPConnection* httpQueue = dynamic_cast<HTTPConnection*>(queue); Boolean isChunkRequest = false; Boolean isFirstError = true; // Note: The WMI Mapper may use a non-HTTPConnection queue here. if (httpQueue) { isChunkRequest = httpQueue->isChunkRequested(); isFirstError = (httpQueue->cimException.getCode() == CIM_ERR_SUCCESS); } // only process the FIRST error if (isFirstError) { // NOTE: even if this error occurs in the middle, HTTPConnection // will flush the entire queued message and reformat. if (isChunkRequest == false) { message = formatError(name, messageId, httpMethod, cimException); } // uri encode the error (for the http header) only when it is // non-chunking or the first error with chunking if (isChunkRequest == false || (isChunkRequest == true && isFirst == true)) { String msg = TraceableCIMException(cimException).getDescription(); String uriEncodedMsg = XmlWriter::encodeURICharacters(msg); CIMException cimExceptionUri( cimException.getCode(), uriEncodedMsg); cimExceptionUri.setContentLanguages( cimException.getContentLanguages()); cimException = cimExceptionUri; } } // if first error in response stream // never put the error in chunked response (because it will end up in // the trailer), so just use the non-error response formatter to send // more data if (isChunkRequest == true) { message = formatResponse( cimName, messageId, httpMethod, contentLanguage, bodyParamsBuf, body, serverTime, isFirst, isLast); } } else { // else non-error condition try { message = formatResponse( cimName, messageId, httpMethod, contentLanguage, bodyParamsBuf, body, serverTime, isFirst, isLast); } catch (PEGASUS_STD(bad_alloc)&) { MessageLoaderParms parms( "Server.CIMOperationResponseEncoder.OUT_OF_MEMORY", "A System error has occurred. Please retry the CIM Operation " "at a later time."); Logger::put_l( Logger::ERROR_LOG, System::CIMSERVER, Logger::WARNING, parms); cimException = PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, parms); // try again with new error and no body body.clear(); sendResponse(response, name, isImplicit); PEG_METHOD_EXIT(); return; } STAT_BYTESSENT } AutoPtr<HTTPMessage> httpMessage( new HTTPMessage(message, 0, &cimException)); httpMessage->setComplete(isLast); httpMessage->setIndex(messageIndex); httpMessage->binaryResponse = response->binaryResponse; if (cimException.getCode() != CIM_ERR_SUCCESS) { httpMessage->contentLanguages = cimException.getContentLanguages(); } else { const OperationContext::Container& container = response->operationContext.get(ContentLanguageListContainer::NAME); const ContentLanguageListContainer& listContainer = *dynamic_cast<const ContentLanguageListContainer*>(&container); contentLanguage = listContainer.getLanguages(); httpMessage->contentLanguages = contentLanguage; } httpMessage->setCloseConnect(closeConnect); queue->enqueue(httpMessage.release()); PEG_METHOD_EXIT(); }
/* Main coté Client */ int main(){ SOCKET sock; header_t header = {-1,-1,-1}; // Servira de header de réception et d'envoi, il faudra juste changer la taille char* message = NULL; char* startMsg; // Permet de connaître la première adresse en mémoire du msg pour pouvoir la libérer par la suite //char* responseForServ = NULL; // La réponse que l'on envoie au serveur int initCo = 1; // Quand initCo == 1 il faut juste envoyer un header au serveur pour qu'il donne un id au client char* responseForServ = NULL; linkedlist_t listResp = NULL; // La liste des réponses de commande command_t command = {NULL, NULL}; while(1){ sock = connectCli("127.0.0.1"); // On veut initialiser la connexion if(initCo == 1){ if(sendHeader(sock, header) == -1){ perror("Erreur dans l'envoi de l'entete au serveur"); exit(EXIT_FAILURE); } printf("Vous etes connecte au serveur.\n"); initCo = 0; // La connexion est initialisé, le serveur va envoyer les données sleep(1); } else if(responseForServ != NULL){ header.size = strlen(responseForServ)+1; if(sendHeader(sock, header) == -1){ perror("Erreur dans l'envoi de l'entete au serveur"); exit(EXIT_FAILURE); } sendMessage(sock, responseForServ); free(responseForServ); } else{ // Aucune réponse à envoyer au serveur header.size = -1; if(sendHeader(sock, header) == -1){ perror("Erreur dans l'envoi de l'entete au serveur"); exit(EXIT_FAILURE); } } // Dans les ca où il n'y a pas de réponse à envoyer, on attend des données du serveur if(recvHeader(sock, &header) == -1){ perror("Erreur dans la réception de l'entete"); exit(EXIT_FAILURE); } if(header.size != -1){ message = NULL; message = recvMessage(sock, header); // Reception du message if(message == NULL){ perror("Erreur dans la reception du message."); exit(EXIT_FAILURE); } startMsg = message; do{ // Récupère et interprète toutes les commandes command = getCommand(&message); listResp = performCommandCli(&command, listResp); command.args = cleanL(command.args, 0); // Vide la liste d'arguments s'il en reste }while(command.name != NULL); fflush(stdout); responseForServ = formatResponse(&listResp); free(startMsg); if(responseForServ == NULL){ sleep(1); // Quand on a pas de réponse, on attend 1 secondes } } else{ // Quand le serveur n'a pas envoyé de messsage if(shutdown(sock, SHUT_RDWR) == -1){ perror("Erreur pendant la fermeture du socket."); exit(EXIT_FAILURE); } close(sock); //sleep(2); // On attend un petit moment } } return EXIT_SUCCESS; }