TITANIUM_FUNCTION(File, createdAt) { const auto ctx = get_context(); const std::vector<JSValue> dateArg = { ctx.CreateNumber(static_cast<double>(createTimestamp().count())) }; return ctx.CreateDate(dateArg); }
virtual void start(detail::TestResult* result = NULL, bool last = false) { assert(_indentCount < 2); if(result == NULL) { _os << "<?xml version='1.0' encoding='UTF-8'?>" << std::endl; return; } if(_indentCount == 0) { _os << "<testsuites>" << std::endl; } else { std::string indent; for(int i = 0; i < _indentCount; ++i) { indent += " "; } size_t tests = result->_success + result->_failed; _os << indent << "<testsuite tests=\"" << tests << "\"" << " name=\"" << result->testName() << "\"" << " time=\"" << result->getRunTime() << "\"" << " id=\"" << _index << "\"" << " package=\"\"" << " timestamp=\"" << createTimestamp(&result->_timestamp) << "\"" << " hostname=\"localhost\"" << " errors=\"" << result->_failed << "\"" << " failures=\"0\"" << " >" << std::endl; _os << indent << indent << "<properties />" << std::endl; _index++; } _indentCount++; }
TITANIUM_FUNCTION(File, createTimestamp) { const auto ctx = get_context(); ctx.JSEvaluateScript("Ti.API.warn('createTimestamp() has been deprecated in 7.2.0 in favor of createdAt() to avoid platform-differences for return type. createdAt() will return a Date object on all platforms.');"); return ctx.CreateNumber(static_cast<double>(createTimestamp().count())); }
OAuthParameters::OAuthParameters() { setHttpMethod("POST"); setNonce(createUniqueNonce()); setTimestamp(createTimestamp()); setSignatureMethod("HMAC-SHA1"); setVerison("1.0"); }
//-------------------------------------------------- // Prepares a new signature for signing and calculates // the final hash value to sign. // pSigDoc - signed document object // ppSigInfo - pointer for address of newly allocated signature // manifest - manifest or role // city - signers address , city // state - signers address , state or province // zip - signers address , postal code // country - signers address , country name // id - id for new signature. Optional, use NULL for default // return returns error code or ERR_OK //-------------------------------------------------- EXP_OPTION int ddocPrepareSignature(SignedDoc* pSigDoc, SignatureInfo** ppSigInfo, const char* manifest, const char* city, const char* state, const char* zip, const char* country, X509* pCert, const char* id) { int err = ERR_OK, l1; DigiDocMemBuf mbuf1, *pMBuf1; char buf1[50]; mbuf1.pMem = 0; mbuf1.nLen = 0; ddocDebug(3, "ddocPrepareSignature", "Preparing signature manifest: %s country: %s, state: %s, city: %s, zip: %s, cert: %s, id: %s", (manifest ? manifest : "NULL"), (country ? country : "NULL"), (state ? state : "NULL"), (city ? city : "NULL"), (zip ? zip : "NULL"), (pCert ? "OK" : "ERROR"), (id ? id : "NULL")); // check mandator fields RETURN_IF_NULL_PARAM(pSigDoc); RETURN_IF_NULL_PARAM(ppSigInfo); RETURN_IF_NULL_PARAM(pCert); clearErrors(); // add new signature err = SignatureInfo_new(ppSigInfo, pSigDoc, id); RETURN_IF_NOT(err == ERR_OK, err); // automatically calculate doc-info elements for this signature addAllDocInfos(pSigDoc, *ppSigInfo); // add signature production place if (city || state || zip || country) err = setSignatureProductionPlace(*ppSigInfo, city, state, zip, country); // add user roles/manifests if (manifest) err = addSignerRole(*ppSigInfo, 0, manifest, -1, 0); RETURN_IF_NOT(err == ERR_OK, err); // add signers certificate err = setSignatureCert(*ppSigInfo, pCert); RETURN_IF_NOT(err == ERR_OK, err); // timestamp createTimestamp(pSigDoc, (char*)buf1, sizeof(buf1)); setString((char**)&((*ppSigInfo)->szTimeStamp), (const char*)buf1, -1); // now calculate signed properties digest err = calculateSignedPropertiesDigest(pSigDoc, *ppSigInfo); // TODO: replace later pMBuf1 = ddocDigestValue_GetDigestValue((*ppSigInfo)->pSigPropDigest); ddocSigInfo_SetSigPropRealDigest(*ppSigInfo, (const char*)pMBuf1->pMem, pMBuf1->nLen); // signature type & val ddocSignatureValue_new(&((*ppSigInfo)->pSigValue), 0, SIGN_RSA_NAME, 0, 0); // calc signed-info digest l1 = sizeof(buf1); err = calculateSignedInfoDigest(pSigDoc, *ppSigInfo, (byte*)buf1, &l1); err = ddocSigInfo_SetSigInfoRealDigest(*ppSigInfo, buf1, l1); // debug output - final hash to sign pMBuf1 = ddocDigestValue_GetDigestValue((*ppSigInfo)->pSigInfoRealDigest); ddocEncodeBase64(pMBuf1, &mbuf1); ddocDebug(3, "ddocPrepareSignature", "signing hash %s len: %d b64len: %d", (char*)mbuf1.pMem, mbuf1.nLen, l1); ddocMemBuf_free(&mbuf1); return err; }
OAuthParameters::OAuthParameters(const OAuthConsumer &consumer, const OAuthToken &token) : Consumer(consumer), Token(token) { setHttpMethod("POST"); setNonce(createUniqueNonce()); setTimestamp(createTimestamp()); setSignatureMethod("HMAC-SHA1"); setVerison("1.0"); }
void vl::LoggerT<T>::add_prelude(std::string& out, LogLevel level) { if (!is_set(pimpl_->options, notimestamp)) safe_sprintf(out, "{0} ", createTimestamp()); if (!is_set(pimpl_->options, nologgername)) safe_sprintf(out, "[{0}] ", pimpl_->name); if (!is_set(pimpl_->options, nothreadid)) safe_sprintf(out, "0x{0:x} ", std::this_thread::get_id()); if (!is_set(pimpl_->options, nologlevel)) safe_sprintf(out, "<{0}> ", getLogLevel(level)); }
void log( std::string logMsg ) { std::ofstream logFile; logFile.open ( Config::getSingletonPtr()->getLogDest(), std::ios::app ); logFile << createTimestamp() << " " << logMsg << std::endl; logFile.close(); }
//============================================================ // Calculates and stores a signature for this SignatureInfo object // Uses EstEID card to sign the info // pSigInfo - signature info object // nSigType - signature type code // keyfile - RSA key file // passwd - key password // certfile - certificate file //============================================================ EXP_OPTION int calculateSignatureWithEstID(SignedDoc* pSigDoc, SignatureInfo* pSigInfo, int slot, const char* passwd) { int err = ERR_OK, nKey; LIBHANDLE pLibrary = 0; CK_ULONG certLen, sigLen, padDigLen; CK_RV rv; CK_SLOT_ID slotids[20], slId = 0; CK_SESSION_HANDLE hSession = 0; CK_OBJECT_HANDLE hPrivateKey, hKeys[20], hCert; char keyId[20][20]; CK_ULONG keyIdLen[20]; CK_BYTE certData[2048]; CK_BYTE sigDig[100], padDig[130]; CK_BYTE signature[256]; CK_BYTE padding[] = { 48, 33, 48, 9, 6, 5, 43, 14, 3, 2, 26, 5, 0, 4, 20 }; CK_BYTE padding256[] = { 48, 49, 48, 13, 6, 9, 96, 134, 72, 1 ,101, 3, 4, 2, 1, 5, 0, 4, 32}; //CK_BYTE padding256[] = { 48, 33, 48, 13, 6, 9, 96, 134, 72, 1 ,101, 3, 4, 2, 1, 5, 0, 4, 32}; char* buf1; int l1, l2; X509* x509; DigiDocMemBuf mbuf1; RETURN_IF_NULL_PARAM(pSigInfo); RETURN_IF_NULL_PARAM(pSigDoc); // try active driver driver first snprintf((char*)signature, sizeof(signature), "DIGIDOC_DRIVER_%d_FILE", ConfigItem_lookup_int("DIGIDOC_DEFAULT_DRIVER", 1)); for(l1 = 0; l1 < 20; l1++) slotids[l1] = INVALID_SLOTIID; // initialize err = loadAndTestDriver(ConfigItem_lookup((const char*)signature), &pLibrary, (CK_SLOT_ID*)slotids, 20, (CK_ULONG)slot); ddocDebug(3, "calculateSignatureWithEstID", "Driver handle: %d err = %d slot: %d", pLibrary, err, slot); RETURN_IF_NOT(err == ERR_OK, err); // inittialize slId = INVALID_SLOTIID; // not found yet //err = ddocLocateSlotWithSignatureCert(pLibrary, slotids, // &slId, (char*)signature, sizeof(signature)); // find suitable slotid for(l1 = 0; l1 < 20; l1++) { if(slotids[l1] != INVALID_SLOTIID) ddocDebug(3, "calculateSignatureWithEstID", "Slot idx: %d = %d", l1, slotids[l1]); if(slotids[l1] != INVALID_SLOTIID && l1 == slot) { slId = slotids[l1]; ddocDebug(3, "calculateSignatureWithEstID", "Select idx: %d slot: %d", l1, slId); } } // open session if(slId != INVALID_SLOTIID) { hSession = OpenSession(slId, passwd); ddocDebug(3, "calculateSignatureWithEstID", "Open sess for slot: %d sess = %uld\n", slId, hSession); if (hSession == CK_INVALID_HANDLE) { err = ERR_PKCS_LOGIN; SET_LAST_ERROR(err); return err; } ddocDebug(3, "calculateSignatureWithEstID", "OpenSession ok, hSession = %d\n", (int)hSession); // get private key for(l1 = 0; l1 < 20; l1++) { memset(keyId[l1], 0, 20); keyIdLen[l1] = 0; } err = LocatePrivateKey(hSession, keyId, keyIdLen, hKeys); //ddocDebug(3, "calculateSignatureWithEstID", "Priv key: %s", keyId); //if (hPrivateKey == CK_INVALID_HANDLE) { err = ERR_PKCS_PK; SET_LAST_ERROR(err); return err; } // get cert memset(certData, 0, sizeof(certData)); certLen = sizeof(certData); hCert = LocateCertificate(hSession, certData, &certLen, keyId, keyIdLen, &nKey); hPrivateKey = hKeys[nKey]; ddocDebug(3, "calculateSignatureWithEstID", "selected priv-key: %ld pos %d id: %s", hPrivateKey, nKey, keyId[nKey]); ddocDebug(3, "calculateSignatureWithEstID", "Cert-len: %ld", certLen); //printf("Cert: %s", certData); if (hCert == (CK_OBJECT_HANDLE)-1) { err = ERR_PKCS_CERT_LOC; SET_LAST_ERROR(err); return err; } // set cert data err = ddocDecodeX509Data(&x509, certData, certLen); if (!x509) { err = ERR_PKCS_CERT_DECODE; } // save cert in file if(ConfigItem_lookup_int("DEBUG_LEVEL", 1) > 3) saveCert(x509, "signer.pem", FILE_FORMAT_PEM); //AM 07.03.08 setSignatureCert for BDOC if(!strcmp(pSigDoc->szFormat, BDOC_XML_1_NAME)) { setSignatureCertBDOC(pSigInfo, x509); }else{ setSignatureCert(pSigInfo, x509); } //AM 12.03.08 //VS 23.02.2010 - not necessary? /*if(!strcmp(pSigDoc->szFormat, BDOC_XML_1_NAME)) { findCAForCertificate(&ppCA, x509); err = bdocSigInfo_addCert(pSigInfo, ppCA, CERTID_TYPE_CA_CERTID); }*/ // FIXME createTimestamp(pSigDoc, (char*)sigDig, sizeof(sigDig)); setString((char**)&(pSigInfo->szTimeStamp), (const char*)sigDig, -1); // Signed properties digest buf1 = createXMLSignedProperties(pSigDoc, pSigInfo, 0); //dumpInFile("sigprop-sign1.txt", buf1); if (!buf1) { err = ERR_NULL_POINTER; SET_LAST_ERROR(err); return err; } mbuf1.pMem = canonicalizeXML((char*)buf1, strlen(buf1)); mbuf1.nLen = strlen((const char*)mbuf1.pMem); ddocDebugWriteFile(4, "sigprop-signed.txt", &mbuf1); l2 = sizeof(sigDig); //AM 24.04.08 if(!strcmp(pSigDoc->szFormat, BDOC_XML_1_NAME)) err = calculateDigest((const byte*)mbuf1.pMem, mbuf1.nLen, BDOC_DIGEST, sigDig, &l2); else err = calculateDigest((const byte*)mbuf1.pMem, mbuf1.nLen, DIGEST_SHA1, sigDig, &l2); free(buf1); ddocMemBuf_free(&mbuf1); if (err != ERR_OK) { SET_LAST_ERROR(err); return err; } ddocSigInfo_SetSigPropDigest(pSigInfo, (const char*)sigDig, l2); ddocSigInfo_SetSigPropRealDigest(pSigInfo, (const char*)sigDig, l2); // create signed info //AM 11.03.08 createXMLSignedInfo for BDOC if(!strcmp(pSigDoc->szFormat, BDOC_XML_1_NAME)) buf1 = createXMLSignedInfoBDoc(pSigDoc, pSigInfo); else buf1 = createXMLSignedInfo(pSigDoc, pSigInfo); if (!buf1) { err = ERR_NULL_POINTER; SET_LAST_ERROR(err); return err ; } // get digest l2 = sizeof(sigDig); /*if(!strcmp(pSigDoc->szFormat, BDOC_XML_1_NAME)) err = calculateDigest((const byte*)buf1, strlen(buf1), BDOC_DIGEST, sigDig, &l2); else*/ err = calculateDigest((const byte*)buf1, strlen(buf1), DIGEST_SHA1, sigDig, &l2); free(buf1); if (err != ERR_OK) { err = ERR_NULL_POINTER; SET_LAST_ERROR(err); return err; } ddocSigInfo_SetSigInfoRealDigest(pSigInfo, (const char*)sigDig, l2); // sign data sigLen = sizeof(signature); memset(signature, 0, sizeof(signature)); // pad PKCS#1 ver 1 /*if(!strcmp(pSigDoc->szFormat, BDOC_XML_1_NAME) && BDOC_DIGEST==DIGEST_SHA256) { padDigLen = 51; memset(padDig, 0, sizeof(padDig)); memcpy(padDig, padding256, 19); memcpy(padDig + 19, sigDig, l2); } else {*/ padDigLen = 35; memset(padDig, 0, sizeof(padDig)); memcpy(padDig, padding, 15); memcpy(padDig + 15, sigDig, l2); //} //rv = RSA_padding_add_PKCS1_type_1(padDig, padDigLen, sigDig, l2); //rv = RSA_padding_check_PKCS1_type_1(sigDig, l2, padDig, padDigLen, padDigLen+1); // checkErrors(); // sign data rv = SignData(hSession, hPrivateKey, signature, &sigLen, padDig, padDigLen); if (rv != CKR_OK) { err = ERR_PKCS_SIGN_DATA; SET_LAST_ERROR(err); return err; } // set signature value ddocSigInfo_SetSignatureValue(pSigInfo, (const char*)signature, (int)sigLen); } // if slotid found if(hSession) closePKCS11Library(pLibrary, hSession); return err; }
//============================================================ // Calculates and stores a signature for this SignatureInfo object // Uses EstEID card to sign the info // pSigInfo - signature info object // nSigType - signature type code // keyfile - RSA key file // passwd - key password // certfile - certificate file //============================================================ EXP_OPTION int calculateSignatureWithEstID(SignedDoc* pSigDoc, SignatureInfo* pSigInfo, int slot, const char* passwd) { int err = ERR_OK, nKey; LIBHANDLE pLibrary = 0; CK_ULONG certLen, sigLen, padDigLen; CK_RV rv; CK_SLOT_ID slotids[20], slId = 0; CK_SESSION_HANDLE hSession = 0; CK_OBJECT_HANDLE hPrivateKey = 0, hKeys[20], hCert; char keyId[20][20], kId[20]; CK_ULONG keyIdLen[20]; CK_BYTE certData[2048]; CK_BYTE sigDig[100], padDig[130]; CK_BYTE signature[256]; CK_BYTE padding[] = { 48, 33, 48, 9, 6, 5, 43, 14, 3, 2, 26, 5, 0, 4, 20 }; //CK_BYTE padding256[] = { 48, 49, 48, 13, 6, 9, 96, 134, 72, 1 ,101, 3, 4, 2, 1, 5, 0, 4, 32}; //CK_BYTE padding256[] = { 48, 33, 48, 13, 6, 9, 96, 134, 72, 1 ,101, 3, 4, 2, 1, 5, 0, 4, 32}; char* buf1; int l1, l2, kILen; X509* x509 = 0; DigiDocMemBuf mbuf1; RETURN_IF_NULL_PARAM(pSigInfo); RETURN_IF_NULL_PARAM(pSigDoc); // try active driver driver first snprintf((char*)signature, sizeof(signature), "DIGIDOC_DRIVER_%d_FILE", ConfigItem_lookup_int("DIGIDOC_DEFAULT_DRIVER", 1)); for(l1 = 0; l1 < 20; l1++) slotids[l1] = INVALID_SLOTIID; // initialize err = loadAndTestDriver(ConfigItem_lookup((const char*)signature), &pLibrary, (CK_SLOT_ID*)slotids, 20, (CK_ULONG)slot); ddocDebug(3, "calculateSignatureWithEstID", "Driver handle: %d err = %d slot: %d", pLibrary, err, slot); RETURN_IF_NOT(err == ERR_OK, err); // inittialize slId = INVALID_SLOTIID; // not found yet // try key-usage check if(ConfigItem_lookup_int("KEY_USAGE_CHECK", 1)) { kILen = sizeof(kId); ddocDebug(3, "calculateSignatureWithEstID", "Find slot by key-usage, slot: %d", slot); err = ddocLocateSlotWithSignatureCert(pLibrary, slotids, &slId, &x509, kId, &kILen, slot, &l1); ddocDebug(3, "calculateSignatureWithEstID", "Select by key-usage slot idx: %d = %d err: %d key-id: %s, kid-len: %d", l1, slId, err, kId, kILen); if(err != ERR_OK || l1 < 0 || l1 >= 20) { SET_LAST_ERROR(ERR_SIGNERS_CERT_NON_REPU); return ERR_SIGNERS_CERT_NON_REPU; } } else { ddocDebug(3, "calculateSignatureWithEstID", "Find slot by slot idx: %d", slot); for(l1 = 0; (l1 < 20) && (slId == INVALID_SLOTIID); l1++) { if(slotids[l1] != INVALID_SLOTIID) ddocDebug(3, "calculateSignatureWithEstID", "Slot idx: %d = %d", l1, slotids[l1]); if(slotids[l1] != INVALID_SLOTIID && l1 == slot) { slId = slotids[l1]; ddocDebug(3, "calculateSignatureWithEstID", "Select idx: %d slot: %d", l1, slId); } // if slotid } // for } // use default if not found by key-id or direct if(slId == INVALID_SLOTIID) { l1 = ConfigItem_lookup_int("DIGIDOC_SIGNATURE_SLOT", 0); if(slotids[l1] != INVALID_SLOTIID) { ddocDebug(3, "calculateSignatureWithEstID", "Select default slot idx: %d = %d", l1, slotids[l1]); slId = slotids[l1]; } } // open session if(slId != INVALID_SLOTIID) { hSession = OpenSession(slId, passwd); ddocDebug(3, "calculateSignatureWithEstID", "Open sess for slot: %d sess = %d", slId, hSession); if (hSession == CK_INVALID_HANDLE) { err = ERR_PKCS_LOGIN; SET_LAST_ERROR(err); return err; } ddocDebug(3, "calculateSignatureWithEstID", "OpenSession ok, hSession1 = %d", (int)hSession); if(!x509) { ddocDebug(3, "calculateSignatureWithEstID", "Cert ok"); // get private key for(l1 = 0; l1 < 20; l1++) { memset(keyId[l1], 0, 20); keyIdLen[l1] = 0; } err = LocatePrivateKey(hSession, keyId, keyIdLen, hKeys); //ddocDebug(3, "calculateSignatureWithEstID", "Priv key: %s", keyId); // // get cert memset(certData, 0, sizeof(certData)); certLen = sizeof(certData); hCert = LocateCertificate(hSession, certData, &certLen, keyId, keyIdLen, &nKey); hPrivateKey = hKeys[nKey]; ddocDebug(3, "calculateSignatureWithEstID", "selected priv-key: %ld pos %d id: %s", hPrivateKey, nKey, keyId[nKey]); ddocDebug(3, "calculateSignatureWithEstID", "Cert-len: %ld", certLen); //printf("Cert: %s", certData); if (hCert == (CK_OBJECT_HANDLE)-1) { err = ERR_PKCS_CERT_LOC; SET_LAST_ERROR(err); return err; } // set cert data err = ddocDecodeX509Data(&x509, certData, certLen); } else { // cert already found //kILen = sizeof(kId); ddocDebug(3, "calculateSignatureWithEstID", "Locate priv key2 id: %s, len: %d, hkey: %d", kId, kILen, hPrivateKey); err = LocatePrivateKeyWithId(hSession, (CK_BYTE_PTR)kId, kILen, &hPrivateKey); ddocDebug(3, "calculateSignatureWithEstID", "Priv key-id: %s len: %d hkey: %d err: %d", kId, kILen, hPrivateKey, err); } ddocDebug(3, "calculateSignatureWithEstID", "Priv key: %d err: %d", hPrivateKey, err); if (hPrivateKey == CK_INVALID_HANDLE) { err = ERR_PKCS_PK; SET_LAST_ERROR(err); return err; } if (!x509) { err = ERR_PKCS_CERT_DECODE; } // save cert in file if(ConfigItem_lookup_int("DEBUG_LEVEL", 1) > 3) saveCert(x509, "signer.pem", FILE_FORMAT_PEM); setSignatureCert(pSigInfo, x509); // FIXME createTimestamp(pSigDoc, (char*)sigDig, sizeof(sigDig)); setString((char**)&(pSigInfo->szTimeStamp), (const char*)sigDig, -1); // Signed properties digest buf1 = createXMLSignedProperties(pSigDoc, pSigInfo, 0); //dumpInFile("sigprop-sign1.txt", buf1); if (!buf1) { err = ERR_NULL_POINTER; SET_LAST_ERROR(err); return err; } mbuf1.pMem = canonicalizeXML((char*)buf1, strlen(buf1)); mbuf1.nLen = strlen((const char*)mbuf1.pMem); ddocDebugWriteFile(4, "sigprop-signed.txt", &mbuf1); l2 = sizeof(sigDig); err = calculateDigest((const byte*)mbuf1.pMem, mbuf1.nLen, DIGEST_SHA1, sigDig, &l2); free(buf1); ddocMemBuf_free(&mbuf1); if (err != ERR_OK) { SET_LAST_ERROR(err); return err; } ddocSigInfo_SetSigPropDigest(pSigInfo, (const char*)sigDig, l2); ddocSigInfo_SetSigPropRealDigest(pSigInfo, (const char*)sigDig, l2); // create signed info buf1 = createXMLSignedInfo(pSigDoc, pSigInfo); if (!buf1) { err = ERR_NULL_POINTER; SET_LAST_ERROR(err); return err ; } // get digest l2 = sizeof(sigDig); err = calculateDigest((const byte*)buf1, strlen(buf1), DIGEST_SHA1, sigDig, &l2); free(buf1); if (err != ERR_OK) { err = ERR_NULL_POINTER; SET_LAST_ERROR(err); return err; } ddocSigInfo_SetSigInfoRealDigest(pSigInfo, (const char*)sigDig, l2); // sign data sigLen = sizeof(signature); memset(signature, 0, sizeof(signature)); // pad PKCS#1 ver 1 padDigLen = 35; memset(padDig, 0, sizeof(padDig)); memcpy(padDig, padding, 15); memcpy(padDig + 15, sigDig, l2); //rv = RSA_padding_add_PKCS1_type_1(padDig, padDigLen, sigDig, l2); //rv = RSA_padding_check_PKCS1_type_1(sigDig, l2, padDig, padDigLen, padDigLen+1); // checkErrors(); // sign data rv = SignData(hSession, hPrivateKey, signature, &sigLen, padDig, padDigLen); if (rv != CKR_OK) { err = ERR_PKCS_SIGN_DATA; SET_LAST_ERROR(err); return err; } // set signature value ddocSigInfo_SetSignatureValue(pSigInfo, (const char*)signature, (int)sigLen); ddocDebug(3, "calculateSignatureWithEstID", "Sig-len: %ld", sigLen); } // if slotid found if(hSession) closePKCS11Library(pLibrary, hSession); return err; }
TITANIUM_FUNCTION(File, createTimestamp) { return get_context().CreateNumber(static_cast<double>(createTimestamp().count())); }
t_int httpTransport::write(t_byteCP _msg, t_int const _size, t_int const _connectionID) { t_int status = _size; std::string data(reinterpret_cast<const char*>(_msg), _size); #if BTG_TRANSPORT_DEBUG BTG_NOTICE("httpTransport::write, size=" << _size); #endif // BTG_TRANSPORT_DEBUG switch (this->direction) { case TO_SERVER: { /* Add HTTP client request headers. Use \r\n for linebreaks * * POST / HTTP/1.1 * Host: < where is this? > * Accept: * / * << no spaces.. but without spaces we would mess up this comment * Content-Type: text/xml * Content-Length: <bytes of data> * * End headers with dual linebreaks (\r\n\r\n) then follow with content-data (_msg). */ std::stringstream ss; ss << "POST / HTTP/1.0\r\n"; // ss << "Host: \r\n"; This is illegal to omit in http/1.1.. so speak http/1.0 then.. ss << "Accept: */*\r\n"; ss << "Accept-Encoding: gzip;q=1, *;q=0.1\r\n"; ss << "Content-Type: text/xml\r\n"; ss << "Content-Length: " << _size << "\r\n"; ss << "\r\n"; // We have to append() the message to a string since // it may contain 0 chars (is this valid with // text/xml?? only unittest does this anyways). std::string buff(ss.str()); buff.append(data); #if BTG_TRANSPORT_DEBUG BTG_NOTICE("httpTransport::write(), Sending to server ("<<buff.length()<<" bytes)"); // << buff); #endif // BTG_TRANSPORT_DEBUG if (!client->write(reinterpret_cast<t_byteCP>(buff.c_str()), buff.length())) { BTG_NOTICE("httpTransport::write(), Failed to write " << buff.length() << " bytes to server"); status = httpTransport::OPERATION_FAILED; } break; } case FROM_SERVER: { tcpClient *c = resolve(_connectionID); if (!c) { BTG_NOTICE("httpTransport::write() Tried to write to unknown connection " << _connectionID << "!"); status = httpTransport::OPERATION_FAILED; break; } httpClient* client = dynamic_cast<httpClient*>(c); #if BTG_TRANSPORT_DEBUG BTG_NOTICE("httpTransport::write(), Using client (" << reinterpret_cast<void*>(client) << ") #" << client->socket->getSockId()); #endif // BTG_TRANSPORT_DEBUG /* Add HTTP server response headers. Use \r\n for linebreaks * * 200 OK * Server: btg-<BUILD> * Date: Sun, 06 Nov 1994 08:49:37 GMT * Content-Type: text/xml * Content-Length: <bytes of data> * Connection: keep-alive * * End headers with dual linebreaks (\r\n\r\n) then follow with content-data (_msg). */ std::string accept_encoding; bool use_gzip = false; if (client->httpRequest.getHeader("Accept-Encoding", accept_encoding)) { if (accept_encoding.find("gzip") != std::string::npos) { use_gzip = true; std::string tmp; #if BTG_TRANSPORT_DEBUG BTG_NOTICE("httpTransport::write(), Using GZIP encoding. Uncompressed size: " << data.length()); // << ": " << buff); #endif // BTG_TRANSPORT_DEBUG try { gzipif->gzip_compress(data, tmp); data = tmp; } catch(...) { use_gzip = false; BTG_ERROR_LOG("gzip_compress failed, not using compression."); } #if BTG_TRANSPORT_DEBUG BTG_NOTICE("httpTransport::write(), compressed size: " << data.length()); // << ": " << buff); #endif // BTG_TRANSPORT_DEBUG } } client->httpRequest.reset(); std::stringstream ss; ss << "HTTP/1.0 200 OK\r\n"; ss << "Server: btg-" << GPD->sBUILD() << "\r\n"; ss << "Date: " << createTimestamp() << "\r\n"; ss << "Content-Type: text/xml\r\n"; ss << "Content-Length: " << data.length() << "\r\n"; ss << "Connection: keep-alive\r\n"; if (use_gzip) { ss << "Content-Encoding: gzip\r\n"; } ss << "\r\n"; std::string buff(ss.str()); buff.append(data); #if BTG_TRANSPORT_DEBUG BTG_NOTICE("httpTransport::write(), Sending to current session"); // << ": " << buff); #endif // BTG_TRANSPORT_DEBUG if (!client->socket->write(reinterpret_cast<t_byteCP>(buff.c_str()), buff.length())) { status = httpTransport::OPERATION_FAILED; } break; } } return status; }
t_int httpTransport::read(dBuffer & _buffer, t_int & _connectionID) { #if BTG_TRANSPORT_DEBUG BTG_NOTICE("httpTransport::read"); #endif // BTG_TRANSPORT_DEBUG t_int status = httpTransport::OPERATION_FAILED; _buffer.erase(); _connectionID = NO_CONNECTION_ID; /// Select on all sockets in the group. socketGroup.doSelect(); if (socketGroup.size() == 0) { // No sockets with data, most likely timeout return status; } switch (this->direction) { case TO_SERVER: { #if BTG_TRANSPORT_DEBUG BTG_NOTICE("httpTransport::read, TO_SERVER"); #endif // BTG_TRANSPORT_DEBUG // We only have one socket in the socketGroup so no // need to determine which socket it was... // The above comment works for tcp/ip sockets, but // not in this class. Added checks. btg::core::os::Socket* socket = 0; if (!socketGroup.getNext(socket)) { return status; } if (client != socket) { return status; } t_int rsize = client->read(sndrec_buffer, buffer_size); if (rsize > 0) { #if BTG_TRANSPORT_DEBUG BTG_NOTICE("httpTransport::read(), TO_SERVER, read " << rsize << " bytes from server"); #endif // BTG_TRANSPORT_DEBUG status = rsize; clientRequest->addBytes(sndrec_buffer, rsize); } if (clientRequest->peek()) { #if BTG_TRANSPORT_DEBUG BTG_NOTICE("httpTransport::read(), TO_SERVER, got a full request."); #endif // BTG_TRANSPORT_DEBUG status = clientRequest->getContent(_buffer); clientRequest->reset(); if ((status == 0) && (clientRequest->abort())) { BTG_NOTICE("httpTransport::read(), TO_SERVER, failed to retreive request! Bad gzip?"); // Probably broken gzip compression, // shutdown. client->shutdown(); } } break; } case FROM_SERVER: { #if BTG_TRANSPORT_DEBUG BTG_NOTICE("httpTransport::read, FROM_SERVER"); #endif // BTG_TRANSPORT_DEBUG // Read from all clients. btg::core::os::Socket* socket = 0; while (socketGroup.getNext(socket)) { if (socket == server) { // A new connection is here this->acceptNewConnections(); continue; } // Got data on a socket httpClient* client = dynamic_cast<httpClient*>( resolve( socket ) ); if (client->socket->deleted()) { #if BTG_TRANSPORT_DEBUG BTG_NOTICE("httpTransport::read: deleting dead client " << client); #endif // BTG_TRANSPORT_DEBUG // Terminate the conneciotn endConnection(client->connectionID); // Client is gone now!! client = 0; // Next socket... continue; } t_int rsize = client->socket->read(sndrec_buffer, buffer_size); if (rsize > 0) { #if BTG_TRANSPORT_DEBUG BTG_NOTICE("httpTransport::read(), FROM_SERVER, read " << rsize << " bytes from client "<< client); #endif // BTG_TRANSPORT_DEBUG client->httpRequest.addBytes(sndrec_buffer, rsize); if (client->httpRequest.abort()) { BTG_NOTICE("httpRequest::read(), Fatal error from client " << client); // << ": " << buff); // A fatal error occured. std::stringstream ss; ss << "HTTP/1.0 400 Bad Request\r\n"; ss << "Server: btg-" << GPD->sBUILD() << "\r\n"; ss << "Date: " << createTimestamp() << "\r\n"; ss << "Connection: close\r\n"; ss << "\r\n"; client->socket->write(reinterpret_cast<t_byteCP>(ss.str().c_str()), ss.str().length()); #if BTG_TRANSPORT_DEBUG BTG_NOTICE("httpTransport::read(), shutting down socket "<< client->socket->getSockId()); #endif // BTG_TRANSPORT_DEBUG client->socket->shutdown(); } if (client->httpRequest.peek()) { rsize = client->httpRequest.getContent(_buffer); if (rsize > 0) { status = rsize; _connectionID = client->connectionID; break; } else if (client->httpRequest.abort()) { #if BTG_TRANSPORT_DEBUG BTG_NOTICE("httpTransport::read(), shutting down socket " << client->socket->getSockId()); #endif // BTG_TRANSPORT_DEBUG // Probably broken gzip // compression, shutdown. client->socket->shutdown(); } } } } // while can read a socket. break; } } return status; }