// Assumption: attribute pairs in the string are separated by '&'. char * extractAttributeValue(const char * searchString, const char * attributeName) { char * attributeValue = nullptr; if (searchString && attributeName) { // search the string for attributeName uint32_t attributeNameSize = PL_strlen(attributeName); char * startOfAttribute = PL_strcasestr(searchString, attributeName); if (startOfAttribute) { startOfAttribute += attributeNameSize; // skip over the attributeName if (startOfAttribute) // is there something after the attribute name { char * endOfAttribute = startOfAttribute ? PL_strchr(startOfAttribute, '&') : nullptr; nsDependentCString attributeValueStr; if (startOfAttribute && endOfAttribute) // is there text after attribute value attributeValueStr.Assign(startOfAttribute, endOfAttribute - startOfAttribute); else // there is nothing left so eat up rest of line. attributeValueStr.Assign(startOfAttribute); // now unescape the string... nsCString unescapedValue; MsgUnescapeString(attributeValueStr, 0, unescapedValue); attributeValue = PL_strdup(unescapedValue.get()); } // if we have a attribute value } // if we have a attribute name } // if we got non-null search string and attribute name values return attributeValue; }
// takes a string like ?size=32&contentType=text/html and returns a new string // containing just the attribute value. i.e you could pass in this string with // an attribute name of 'size=', this will return 32 // Assumption: attribute pairs in the string are separated by '&'. void extractAttributeValue(const char * searchString, const char * attributeName, nsCString& result) { //NS_ENSURE_ARG_POINTER(extractAttributeValue); result.Truncate(); if (searchString && attributeName) { // search the string for attributeName PRUint32 attributeNameSize = strlen(attributeName); const char * startOfAttribute = PL_strcasestr(searchString, attributeName); if (startOfAttribute && ( *(startOfAttribute-1) == '?' || *(startOfAttribute-1) == '&') ) { startOfAttribute += attributeNameSize; // skip over the attributeName if (*startOfAttribute) // is there something after the attribute name { const char * endofAttribute = strchr(startOfAttribute, '&'); if (endofAttribute) result.Assign(Substring(startOfAttribute, endofAttribute)); else result.Assign(startOfAttribute); } // if we have a attribute value } // if we have a attribute name } // if we got non-null search string and attribute name values }
PRBool nsHttpResponseHead::IsResumable() { // even though some HTTP/1.0 servers may support byte range requests, we're not // going to bother with them, since those servers wouldn't understand If-Range. return mVersion >= NS_HTTP_VERSION_1_1 && PeekHeader(nsHttp::Content_Length) && (PeekHeader(nsHttp::ETag) || PeekHeader(nsHttp::Last_Modified)) && PL_strcasestr(PeekHeader(nsHttp::Accept_Ranges), "bytes"); }
PRBool nsHttpResponseHead::MustValidateIfExpired() { // according to RFC2616, section 14.9.4: // // When the must-revalidate directive is present in a response received by a // cache, that cache MUST NOT use the entry after it becomes stale to respond to // a subsequent request without first revalidating it with the origin server. // const char *val = PeekHeader(nsHttp::Cache_Control); return val && PL_strcasestr(val, "must-revalidate"); }
NS_IMETHODIMP nsMsgMailNewsUrl::SetSpec(const nsACString &aSpec) { nsCAutoString spec(aSpec); // Parse out "filename" attribute if present. char *start, *end; start = PL_strcasestr(spec.BeginWriting(),FILENAME_PART); if (start) { // Make sure we only get our own value. end = PL_strcasestr((char*)(start+FILENAME_PART_LEN),"&"); if (end) { *end = 0; mAttachmentFileName = start+FILENAME_PART_LEN; *end = '&'; } else mAttachmentFileName = start+FILENAME_PART_LEN; } // Now, set the rest. return m_baseURL->SetSpec(aSpec); }
static void dprintf(const char *format, ...) { va_list ap; Str255 buffer; va_start(ap, format); buffer[0] = std::vsnprintf((char *)buffer + 1, sizeof(buffer) - 1, format, ap); va_end(ap); if (PL_strcasestr((char *)&buffer[1], "warning")) printf("ะตะตะต%s\n", (char*)buffer + 1); else DebugStr(buffer); }
void nsHttpChannelAuthProvider::ParseRealm(const char *challenge, nsACString &realm) { // // From RFC2617 section 1.2, the realm value is defined as such: // // realm = "realm" "=" realm-value // realm-value = quoted-string // // but, we'll accept anything after the the "=" up to the first space, or // end-of-line, if the string is not quoted. // const char *p = PL_strcasestr(challenge, "realm="); if (p) { bool has_quote = false; p += 6; if (*p == '"') { has_quote = true; p++; } const char *end; if (has_quote) { end = p; while (*end) { if (*end == '\\') { // escaped character, store that one instead if not zero if (!*++end) break; } else if (*end == '\"') // end of string break; realm.Append(*end); ++end; } } else { // realm given without quotes end = strchr(p, ' '); if (end) realm.Assign(p, end - p); else realm.Assign(p); } } }
// Return the value of the (HTTP 1.1) max-age directive, which itself is a // component of the Cache-Control response header nsresult nsHttpResponseHead::GetMaxAgeValue(PRUint32 *result) { const char *val = PeekHeader(nsHttp::Cache_Control); if (!val) return NS_ERROR_NOT_AVAILABLE; const char *p = PL_strcasestr(val, "max-age="); if (!p) return NS_ERROR_NOT_AVAILABLE; *result = (PRUint32) atoi(p + 8); return NS_OK; }
PRBool nsMsgMdnGenerator::NotInToOrCc() { DEBUG_MDN("nsMsgMdnGenerator::NotInToOrCc"); nsCString reply_to; nsCString to; nsCString cc; m_identity->GetReplyTo(reply_to); m_headers->ExtractHeader(HEADER_TO, PR_TRUE, getter_Copies(to)); m_headers->ExtractHeader(HEADER_CC, PR_TRUE, getter_Copies(cc)); // start with a simple check if ((!to.IsEmpty() && PL_strcasestr(to.get(), m_email.get())) || (!cc.IsEmpty() && PL_strcasestr(cc.get(), m_email.get()))) { return PR_FALSE; } if ((!reply_to.IsEmpty() && !to.IsEmpty() && PL_strcasestr(to.get(), reply_to.get())) || (!reply_to.IsEmpty() && !cc.IsEmpty() && PL_strcasestr(cc.get(), reply_to.get()))) { return PR_FALSE; } return PR_TRUE; }
static int sign_all_arc_fn(char *relpath, char *basedir, char *reldir, char *filename, void *arg) { char *zipfile = NULL; char *arc = NULL, *archive = NULL; int retval = 0; SignArcInfo * infop = (SignArcInfo * )arg; /* Make sure there is one and only one ".arc" in the relative path, * and that it is at the end of the path (don't sign .arcs within .arcs) */ if ( (PL_strcaserstr(relpath, ".arc") == relpath + strlen(relpath) - 4) && (PL_strcasestr(relpath, ".arc") == relpath + strlen(relpath) - 4) ) { if (!infop) { PR_fprintf(errorFD, "%s: Internal failure\n", PROGRAM_NAME); errorCount++; retval = -1; goto finish; } archive = PR_smprintf("%s/%s", basedir, relpath); zipfile = PL_strdup(archive); arc = PORT_Strrchr (zipfile, '.'); if (arc == NULL) { PR_fprintf(errorFD, "%s: Internal failure\n", PROGRAM_NAME); errorCount++; retval = -1; goto finish; } PL_strcpy (arc, ".jar"); if (verbosity >= 0) { PR_fprintf(outputFD, "\nsigning: %s\n", zipfile); } retval = SignArchive(archive, infop->keyName, zipfile, infop->javascript, infop->metafile, infop->install_script, infop->optimize, PR_TRUE /* recurse */); } finish: if (archive) PR_Free(archive); if (zipfile) PR_Free(zipfile); return retval; }
static int plugin_mr_get_type(struct slapdplugin *pi) { int rc = LDAP_FILTER_EQUALITY; if (pi) { char **str = pi->plg_mr_names; for (; str && *str; ++str) { if (PL_strcasestr(*str, "substr")) { rc = LDAP_FILTER_SUBSTRINGS; break; } if (PL_strcasestr(*str, "approx")) { rc = LDAP_FILTER_APPROX; break; } if (PL_strcasestr(*str, "ordering")) { rc = LDAP_FILTER_GE; break; } } } return rc; }
static void LogHeaders(const char *lines) { nsCAutoString buf; char *p; while ((p = PL_strstr(lines, "\r\n")) != nsnull) { buf.Assign(lines, p - lines); if (PL_strcasestr(buf.get(), "authorization: ") != nsnull) { char *p = PL_strchr(PL_strchr(buf.get(), ' ')+1, ' '); while (*++p) *p = '*'; } LOG3((" %s\n", buf.get())); lines = p + 2; } }
// Return the value of the (HTTP 1.1) max-age directive, which itself is a // component of the Cache-Control response header nsresult nsHttpResponseHead::GetMaxAgeValue(uint32_t *result) const { const char *val = PeekHeader(nsHttp::Cache_Control); if (!val) return NS_ERROR_NOT_AVAILABLE; const char *p = PL_strcasestr(val, "max-age="); if (!p) return NS_ERROR_NOT_AVAILABLE; int maxAgeValue = atoi(p + 8); if (maxAgeValue < 0) maxAgeValue = 0; *result = uint32_t(maxAgeValue); return NS_OK; }
// Ok, if we are here, and we have a aCharset passed in that is not // UTF-8 or US-ASCII, then we should tag the mChannel member with this // charset. This is because replying to messages with specified charset's // need to be tagged as that charset by default. // NS_IMETHODIMP nsMimeBaseEmitter::UpdateCharacterSet(const char *aCharset) { if ( (aCharset) && (PL_strcasecmp(aCharset, "US-ASCII")) && (PL_strcasecmp(aCharset, "ISO-8859-1")) && (PL_strcasecmp(aCharset, "UTF-8")) ) { nsAutoCString contentType; if (NS_SUCCEEDED(mChannel->GetContentType(contentType)) && !contentType.IsEmpty()) { char *cBegin = contentType.BeginWriting(); const char *cPtr = PL_strcasestr(cBegin, "charset="); if (cPtr) { char *ptr = cBegin; while (*ptr) { if ( (*ptr == ' ') || (*ptr == ';') ) { if ((ptr + 1) >= cPtr) { *ptr = '\0'; break; } } ++ptr; } } // have to set content-type since it could have an embedded null byte mChannel->SetContentType(nsDependentCString(cBegin)); mChannel->SetContentCharset(nsDependentCString(aCharset)); } } return NS_OK; }
bool nsGIOProtocolHandler::IsSupportedProtocol(const nsCString &aSpec) { const char *specString = aSpec.get(); const char *colon = strchr(specString, ':'); if (!colon) return false; uint32_t length = colon - specString + 1; // <scheme> + ':' nsCString scheme(specString, length); char *found = PL_strcasestr(mSupportedProtocols.get(), scheme.get()); if (!found) return false; if (found[length] != ',' && found[length] != '\0') return false; return true; }
void nsHttpChannelAuthProvider::ParseRealm(const char *challenge, nsACString &realm) { // // From RFC2617 section 1.2, the realm value is defined as such: // // realm = "realm" "=" realm-value // realm-value = quoted-string // // but, we'll accept anything after the the "=" up to the first space, or // end-of-line, if the string is not quoted. // const char *p = PL_strcasestr(challenge, "realm="); if (p) { bool has_quote = false; p += 6; if (*p == '"') { has_quote = true; p++; } const char *end = p; while (*end && has_quote) { // Loop through all the string characters to find the closing // quote, ignoring escaped quotes. if (*end == '"' && end[-1] != '\\') break; ++end; } if (!has_quote) end = strchr(p, ' '); if (end) realm.Assign(p, end - p); else realm.Assign(p); } }
PRBool nsGnomeVFSProtocolHandler::IsSupportedProtocol(const nsCString &aSpec) { const char *specString = aSpec.get(); const char *colon = strchr(specString, ':'); if (!colon) return PR_FALSE; PRUint32 length = colon - specString + 1; // <scheme> + ':' nsCString scheme(specString, length); char *found = PL_strcasestr(mSupportedProtocols.get(), scheme.get()); if (!found) return PR_FALSE; if (found[length] != ',' && found[length] != '\0') return PR_FALSE; return PR_TRUE; }
// Copied from image/decoders/icon/nsIconURI.cpp // takes a string like ?size=32&contentType=text/html and returns a new string // containing just the attribute values. i.e you could pass in this string with // an attribute name of "size=", this will return 32 // Assumption: attribute pairs are separated by & void extractAttributeValue(const char* searchString, const char* attributeName, nsCString& result) { result.Truncate(); if (!searchString || !attributeName) return; PRUint32 attributeNameSize = strlen(attributeName); const char *startOfAttribute = PL_strcasestr(searchString, attributeName); if (!startOfAttribute || !( *(startOfAttribute-1) == '?' || *(startOfAttribute-1) == '&') ) return; startOfAttribute += attributeNameSize; // Skip the attributeName if (!*startOfAttribute) return; const char *endOfAttribute = strchr(startOfAttribute, '&'); if (endOfAttribute) { result.Assign(Substring(startOfAttribute, endOfAttribute)); } else { result.Assign(startOfAttribute); } }
int handle_connection( PRFileDesc *tcp_sock, PRFileDesc *model_sock, int requestCert) { PRFileDesc *ssl_sock = NULL; PRFileDesc *local_file_fd = NULL; char *pBuf; /* unused space at end of buf */ const char *errString; PRStatus status; int bufRem; /* unused bytes at end of buf */ int bufDat; /* characters received in buf */ int newln = 0; /* # of consecutive newlns */ int firstTime = 1; int reqLen; int rv; int numIOVs; PRSocketOptionData opt; PRIOVec iovs[16]; char msgBuf[160]; char buf[10240]; char fileName[513]; char *getData = NULL; /* inplace conversion */ SECItem postData; PRBool isOcspRequest = PR_FALSE; PRBool isPost; postData.data = NULL; postData.len = 0; pBuf = buf; bufRem = sizeof buf; VLOG(("httpserv: handle_connection: starting")); opt.option = PR_SockOpt_Nonblocking; opt.value.non_blocking = PR_FALSE; PR_SetSocketOption(tcp_sock, &opt); VLOG(("httpserv: handle_connection: starting\n")); ssl_sock = tcp_sock; if (noDelay) { opt.option = PR_SockOpt_NoDelay; opt.value.no_delay = PR_TRUE; status = PR_SetSocketOption(ssl_sock, &opt); if (status != PR_SUCCESS) { errWarn("PR_SetSocketOption(PR_SockOpt_NoDelay, PR_TRUE)"); if (ssl_sock) { PR_Close(ssl_sock); } return SECFailure; } } while (1) { const char *post; const char *foundStr = NULL; const char *tmp = NULL; newln = 0; reqLen = 0; rv = PR_Read(ssl_sock, pBuf, bufRem - 1); if (rv == 0 || (rv < 0 && PR_END_OF_FILE_ERROR == PR_GetError())) { if (verbose) errWarn("HDX PR_Read hit EOF"); break; } if (rv < 0) { errWarn("HDX PR_Read"); goto cleanup; } /* NULL termination */ pBuf[rv] = 0; if (firstTime) { firstTime = 0; } pBuf += rv; bufRem -= rv; bufDat = pBuf - buf; /* Parse the input, starting at the beginning of the buffer. * Stop when we detect two consecutive \n's (or \r\n's) * as this signifies the end of the GET or POST portion. * The posted data follows. */ while (reqLen < bufDat && newln < 2) { int octet = buf[reqLen++]; if (octet == '\n') { newln++; } else if (octet != '\r') { newln = 0; } } /* came to the end of the buffer, or second newln * If we didn't get an empty line (CRLFCRLF) then keep on reading. */ if (newln < 2) continue; /* we're at the end of the HTTP request. * If the request is a POST, then there will be one more * line of data. * This parsing is a hack, but ok for SSL test purposes. */ post = PORT_Strstr(buf, "POST "); if (!post || *post != 'P') break; postData.data = (void *)(buf + reqLen); tmp = "content-length: "; foundStr = PL_strcasestr(buf, tmp); if (foundStr) { int expectedPostLen; int havePostLen; expectedPostLen = atoi(foundStr + strlen(tmp)); havePostLen = bufDat - reqLen; if (havePostLen >= expectedPostLen) { postData.len = expectedPostLen; break; } } else { /* use legacy hack */ /* It's a post, so look for the next and final CR/LF. */ while (reqLen < bufDat && newln < 3) { int octet = buf[reqLen++]; if (octet == '\n') { newln++; } } if (newln == 3) break; } } /* read loop */ bufDat = pBuf - buf; if (bufDat) do { /* just close if no data */ /* Have either (a) a complete get, (b) a complete post, (c) EOF */ if (reqLen > 0) { PRBool isGetOrPost = PR_FALSE; unsigned skipChars = 0; isPost = PR_FALSE; if (!strncmp(buf, getCmd, sizeof getCmd - 1)) { isGetOrPost = PR_TRUE; skipChars = 4; } else if (!strncmp(buf, "POST ", 5)) { isGetOrPost = PR_TRUE; isPost = PR_TRUE; skipChars = 5; } if (isGetOrPost) { char *fnBegin = buf; char *fnEnd; char *fnstart = NULL; PRFileInfo info; fnBegin += skipChars; fnEnd = strpbrk(fnBegin, " \r\n"); if (fnEnd) { int fnLen = fnEnd - fnBegin; if (fnLen < sizeof fileName) { strncpy(fileName, fnBegin, fnLen); fileName[fnLen] = 0; /* null terminate */ fnstart = fileName; /* strip initial / because our root is the current directory*/ while (*fnstart && *fnstart == '/') ++fnstart; } } if (fnstart) { if (!strncmp(fnstart, "ocsp", 4)) { if (isPost) { if (postData.data) { isOcspRequest = PR_TRUE; } } else { if (!strncmp(fnstart, "ocsp/", 5)) { isOcspRequest = PR_TRUE; getData = fnstart + 5; } } } else { /* try to open the file named. * If successful, then write it to the client. */ status = PR_GetFileInfo(fnstart, &info); if (status == PR_SUCCESS && info.type == PR_FILE_FILE && info.size >= 0) { local_file_fd = PR_Open(fnstart, PR_RDONLY, 0); } } } } } numIOVs = 0; iovs[numIOVs].iov_base = (char *)outHeader; iovs[numIOVs].iov_len = (sizeof(outHeader)) - 1; numIOVs++; if (isOcspRequest && caRevoInfos) { CERTOCSPRequest *request = NULL; PRBool failThisRequest = PR_FALSE; PLArenaPool *arena = NULL; if (ocspMethodsAllowed == ocspGetOnly && postData.len) { failThisRequest = PR_TRUE; } else if (ocspMethodsAllowed == ocspPostOnly && getData) { failThisRequest = PR_TRUE; } else if (ocspMethodsAllowed == ocspRandomGetFailure && getData) { if (!(rand() % 2)) { failThisRequest = PR_TRUE; } } if (failThisRequest) { PR_Write(ssl_sock, outBadRequestHeader, strlen(outBadRequestHeader)); break; } /* get is base64, post is binary. * If we have base64, convert into the (empty) postData array. */ if (getData) { if (urldecode_base64chars_inplace(getData) == SECSuccess) { /* The code below can handle a NULL arena */ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); NSSBase64_DecodeBuffer(arena, &postData, getData, strlen(getData)); } } if (postData.len) { request = CERT_DecodeOCSPRequest(&postData); } if (arena) { PORT_FreeArena(arena, PR_FALSE); } if (!request || !request->tbsRequest || !request->tbsRequest->requestList || !request->tbsRequest->requestList[0]) { PORT_Sprintf(msgBuf, "Cannot decode OCSP request.\r\n"); iovs[numIOVs].iov_base = msgBuf; iovs[numIOVs].iov_len = PORT_Strlen(msgBuf); numIOVs++; } else { /* TODO: support more than one request entry */ CERTOCSPCertID *reqid = request->tbsRequest->requestList[0]->reqCert; const caRevoInfo *revoInfo = NULL; PRBool unknown = PR_FALSE; PRBool revoked = PR_FALSE; PRTime nextUpdate = 0; PRTime revoDate = 0; PRCList *caRevoIter; caRevoIter = &caRevoInfos->link; do { CERTOCSPCertID *caid; revoInfo = (caRevoInfo *)caRevoIter; caid = revoInfo->id; if (SECOID_CompareAlgorithmID(&reqid->hashAlgorithm, &caid->hashAlgorithm) == SECEqual && SECITEM_CompareItem(&reqid->issuerNameHash, &caid->issuerNameHash) == SECEqual && SECITEM_CompareItem(&reqid->issuerKeyHash, &caid->issuerKeyHash) == SECEqual) { break; } revoInfo = NULL; caRevoIter = PR_NEXT_LINK(caRevoIter); } while (caRevoIter != &caRevoInfos->link); if (!revoInfo) { unknown = PR_TRUE; revoInfo = caRevoInfos; } else { CERTCrl *crl = &revoInfo->crl->crl; CERTCrlEntry *entry = NULL; DER_DecodeTimeChoice(&nextUpdate, &crl->nextUpdate); if (crl->entries) { int iv = 0; /* assign, not compare */ while ((entry = crl->entries[iv++])) { if (SECITEM_CompareItem(&reqid->serialNumber, &entry->serialNumber) == SECEqual) { break; } } } if (entry) { /* revoked status response */ revoked = PR_TRUE; DER_DecodeTimeChoice(&revoDate, &entry->revocationDate); } else { /* else good status response */ if (!isPost && ocspMethodsAllowed == ocspGetUnknown) { unknown = PR_TRUE; nextUpdate = PR_Now() + (PRTime)60 * 60 * 24 * PR_USEC_PER_SEC; /*tomorrow*/ revoDate = PR_Now() - (PRTime)60 * 60 * 24 * PR_USEC_PER_SEC; /*yesterday*/ } } } { PRTime now = PR_Now(); PLArenaPool *arena = NULL; CERTOCSPSingleResponse *sr; CERTOCSPSingleResponse **singleResponses; SECItem *ocspResponse; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (unknown) { sr = CERT_CreateOCSPSingleResponseUnknown(arena, reqid, now, &nextUpdate); } else if (revoked) { sr = CERT_CreateOCSPSingleResponseRevoked(arena, reqid, now, &nextUpdate, revoDate, NULL); } else { sr = CERT_CreateOCSPSingleResponseGood(arena, reqid, now, &nextUpdate); } /* meaning of value 2: one entry + one end marker */ singleResponses = PORT_ArenaNewArray(arena, CERTOCSPSingleResponse *, 2); singleResponses[0] = sr; singleResponses[1] = NULL; ocspResponse = CERT_CreateEncodedOCSPSuccessResponse(arena, revoInfo->cert, ocspResponderID_byName, now, singleResponses, &pwdata); if (!ocspResponse) { PORT_Sprintf(msgBuf, "Failed to encode response\r\n"); iovs[numIOVs].iov_base = msgBuf; iovs[numIOVs].iov_len = PORT_Strlen(msgBuf); numIOVs++; } else { PR_Write(ssl_sock, outOcspHeader, strlen(outOcspHeader)); PR_Write(ssl_sock, ocspResponse->data, ocspResponse->len); PORT_FreeArena(arena, PR_FALSE); } } CERT_DestroyOCSPRequest(request); break; } } else if (local_file_fd) { PRInt32 bytes; int errLen; bytes = PR_TransmitFile(ssl_sock, local_file_fd, outHeader, sizeof outHeader - 1, PR_TRANSMITFILE_KEEP_OPEN, PR_INTERVAL_NO_TIMEOUT); if (bytes >= 0) { bytes -= sizeof outHeader - 1; FPRINTF(stderr, "httpserv: PR_TransmitFile wrote %d bytes from %s\n", bytes, fileName); break; } errString = errWarn("PR_TransmitFile"); errLen = PORT_Strlen(errString); errLen = PR_MIN(errLen, sizeof msgBuf - 1); PORT_Memcpy(msgBuf, errString, errLen); msgBuf[errLen] = 0; iovs[numIOVs].iov_base = msgBuf; iovs[numIOVs].iov_len = PORT_Strlen(msgBuf); numIOVs++; } else if (reqLen <= 0) { /* hit eof */ PORT_Sprintf(msgBuf, "Get or Post incomplete after %d bytes.\r\n", bufDat); iovs[numIOVs].iov_base = msgBuf; iovs[numIOVs].iov_len = PORT_Strlen(msgBuf); numIOVs++; } else if (reqLen < bufDat) { PORT_Sprintf(msgBuf, "Discarded %d characters.\r\n", bufDat - reqLen); iovs[numIOVs].iov_base = msgBuf; iovs[numIOVs].iov_len = PORT_Strlen(msgBuf); numIOVs++; } if (reqLen > 0) { if (verbose > 1) fwrite(buf, 1, reqLen, stdout); /* display it */ iovs[numIOVs].iov_base = buf; iovs[numIOVs].iov_len = reqLen; numIOVs++; } rv = PR_Writev(ssl_sock, iovs, numIOVs, PR_INTERVAL_NO_TIMEOUT); if (rv < 0) { errWarn("PR_Writev"); break; } } while (0);
static int MimeMessage_close_headers (MimeObject *obj) { MimeMessage *msg = (MimeMessage *) obj; int status = 0; char *ct = 0; /* Content-Type header */ MimeObject *body; if (msg->hdrs) { PRBool outer_p = !obj->headers; /* is this the outermost message? */ #ifdef MIME_DRAFTS if (outer_p && obj->options && (obj->options->decompose_file_p || obj->options->caller_need_root_headers) && obj->options->decompose_headers_info_fn) { #ifdef ENABLE_SMIME if (obj->options->decrypt_p && !mime_crypto_object_p (msg->hdrs, PR_FALSE)) obj->options->decrypt_p = PR_FALSE; #endif /* ENABLE_SMIME */ if (!obj->options->caller_need_root_headers || (obj == obj->options->state->root)) status = obj->options->decompose_headers_info_fn ( obj->options->stream_closure, msg->hdrs ); } #endif /* MIME_DRAFTS */ /* If this is the outermost message, we need to run the `generate_header' callback. This happens here instead of in `parse_begin', because it's only now that we've parsed our headers. However, since this is the outermost message, we have yet to write any HTML, so that's fine. */ if (outer_p && obj->output_p && obj->options && obj->options->write_html_p && obj->options->generate_header_html_fn) { int lstatus = 0; char *html = 0; /* The generate_header_html_fn might return HTML, so it's important that the output stream be set up with the proper type before we make the MimeObject_write() call below. */ if (!obj->options->state->first_data_written_p) { lstatus = MimeObject_output_init (obj, TEXT_HTML); if (lstatus < 0) return lstatus; PR_ASSERT(obj->options->state->first_data_written_p); } html = obj->options->generate_header_html_fn(NULL, obj->options->html_closure, msg->hdrs); if (html) { lstatus = MimeObject_write(obj, html, strlen(html), PR_FALSE); PR_Free(html); if (lstatus < 0) return lstatus; } } /* Find the content-type of the body of this message. */ { PRBool ok = PR_TRUE; char *mv = MimeHeaders_get (msg->hdrs, HEADER_MIME_VERSION, PR_TRUE, PR_FALSE); #ifdef REQUIRE_MIME_VERSION_HEADER /* If this is the outermost message, it must have a MIME-Version header with the value 1.0 for us to believe what might be in the Content-Type header. If the MIME-Version header is not present, we must treat this message as untyped. */ ok = (mv && !strcmp(mv, "1.0")); #else /* #### actually, we didn't check this in Mozilla 2.0, and checking it now could cause some compatibility nonsense, so for now, let's just believe any Content-Type header we see. */ ok = PR_TRUE; #endif if (ok) { ct = MimeHeaders_get (msg->hdrs, HEADER_CONTENT_TYPE, PR_TRUE, PR_FALSE); /* If there is no Content-Type header, but there is a MIME-Version header, then assume that this *is* in fact a MIME message. (I've seen messages with MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable and no Content-Type, and we should treat those as being of type MimeInlineTextPlain rather than MimeUntypedText.) */ if (mv && !ct) ct = strdup(TEXT_PLAIN); } PR_FREEIF(mv); /* done with this now. */ } /* If this message has a body which is encrypted and we're going to decrypt it (whithout converting it to HTML, since decrypt_p and write_html_p are never true at the same time) */ if (obj->output_p && obj->options && obj->options->decrypt_p #ifdef ENABLE_SMIME && !mime_crypto_object_p (msg->hdrs, PR_FALSE) #endif /* ENABLE_SMIME */ ) { /* The body of this message is not an encrypted object, so we need to turn off the decrypt_p flag (to prevent us from s#$%ing the body of the internal object up into one.) In this case, our output will end up being identical to our input. */ obj->options->decrypt_p = PR_FALSE; } /* Emit the HTML for this message's headers. Do this before creating the object representing the body. */ if (obj->output_p && obj->options && obj->options->write_html_p) { /* If citation headers are on, and this is not the outermost message, turn them off. */ if (obj->options->headers == MimeHeadersCitation && !outer_p) obj->options->headers = MimeHeadersSome; /* Emit a normal header block. */ status = MimeMessage_write_headers_html(obj); if (status < 0) return status; } else if (obj->output_p) { /* Dump the headers, raw. */ status = MimeObject_write(obj, "", 0, PR_FALSE); /* initialize */ if (status < 0) return status; status = MimeHeaders_write_raw_headers(msg->hdrs, obj->options, obj->options->decrypt_p); if (status < 0) return status; } #ifdef XP_UNIX if (outer_p && obj->output_p) /* Kludge from mimehdrs.c */ MimeHeaders_do_unix_display_hook_hack(msg->hdrs); #endif /* XP_UNIX */ } /* Never put out a separator after a message header block. */ if (obj->options && obj->options->state) obj->options->state->separator_suppressed_p = PR_TRUE; #ifdef MIME_DRAFTS if ( !obj->headers && /* outer most message header */ obj->options && obj->options->decompose_file_p && ct ) obj->options->is_multipart_msg = PL_strcasestr(ct, "multipart/") != NULL; #endif /* MIME_DRAFTS */ body = mime_create(ct, msg->hdrs, obj->options); PR_FREEIF(ct); if (!body) return MIME_OUT_OF_MEMORY; status = ((MimeContainerClass *) obj->clazz)->add_child (obj, body); if (status < 0) { mime_free(body); return status; } // Only do this if this is a Text Object! if ( mime_typep(body, (MimeObjectClass *) &mimeInlineTextClass) ) { ((MimeInlineText *) body)->needUpdateMsgWinCharset = PR_TRUE; } /* Now that we've added this new object to our list of children, start its parser going. */ status = body->clazz->parse_begin(body); if (status < 0) return status; // Now notify the emitter if this is the outer most message, unless // it is a part that is not the head of the message. If it's a part, // we need to figure out the content type/charset of the part // PRBool outer_p = !obj->headers; /* is this the outermost message? */ if ( outer_p && (!obj->options->part_to_load || obj->options->format_out == nsMimeOutput::nsMimeMessageBodyDisplay)) { // call SetMailCharacterSetToMsgWindow() to set a menu charset if (mime_typep(body, (MimeObjectClass *) &mimeInlineTextClass)) { MimeInlineText *text = (MimeInlineText *) body; if (text && text->charset && *text->charset) SetMailCharacterSetToMsgWindow(body, text->charset); } char *msgID = MimeHeaders_get (msg->hdrs, HEADER_MESSAGE_ID, PR_FALSE, PR_FALSE); const char *outCharset = NULL; if (!obj->options->force_user_charset) /* Only convert if the user prefs is false */ outCharset = "UTF-8"; mimeEmitterStartBody(obj->options, (obj->options->headers == MimeHeadersNone), msgID, outCharset); PR_FREEIF(msgID); // setting up truncated message html fotter function char *xmoz = MimeHeaders_get(msg->hdrs, HEADER_X_MOZILLA_STATUS, PR_FALSE, PR_FALSE); if (xmoz) { PRUint32 flags = 0; char dummy = 0; if (sscanf(xmoz, " %lx %c", &flags, &dummy) == 1 && flags & MSG_FLAG_PARTIAL) { obj->options->html_closure = obj; obj->options->generate_footer_html_fn = MimeMessage_partial_message_html; } PR_FREEIF(xmoz); } } return 0; }
static int MimeObject_parse_begin (MimeObject *obj) { NS_ASSERTION (!obj->closed_p, "object shouldn't be already closed"); /* If we haven't set up the state object yet, then this should be the outermost object... */ if (obj->options && !obj->options->state) { NS_ASSERTION(!obj->headers, "headers should be null"); /* should be the outermost object. */ obj->options->state = new MimeParseStateObject; if (!obj->options->state) return MIME_OUT_OF_MEMORY; obj->options->state->root = obj; obj->options->state->separator_suppressed_p = PR_TRUE; /* no first sep */ const char *delParts = PL_strcasestr(obj->options->url, "&del="); const char *detachLocations = PL_strcasestr(obj->options->url, "&detachTo="); if (delParts) { const char *delEnd = PL_strcasestr(delParts + 1, "&"); if (!delEnd) delEnd = delParts + strlen(delParts); ParseString(Substring(delParts + 5, delEnd), ',', obj->options->state->partsToStrip); } if (detachLocations) { detachLocations += 10; // advance past "&detachTo=" ParseString(nsDependentCString(detachLocations), ',', obj->options->state->detachToFiles); } } /* Decide whether this object should be output or not... */ if (!obj->options || !obj->options->output_fn /* if we are decomposing the message in files and processing a multipart object, we must not output it without parsing it first */ || (obj->options->decompose_file_p && obj->options->decompose_file_output_fn && mime_typep(obj, (MimeObjectClass*) &mimeMultipartClass)) ) obj->output_p = PR_FALSE; else if (!obj->options->part_to_load) obj->output_p = PR_TRUE; else { char *id = mime_part_address(obj); if (!id) return MIME_OUT_OF_MEMORY; // We need to check if a part is the subpart of the part to load. // If so and this is a raw or body display output operation, then // we should mark the part for subsequent output. // // First, check for an exact match obj->output_p = !strcmp(id, obj->options->part_to_load); if (!obj->output_p && (obj->options->format_out == nsMimeOutput::nsMimeMessageRaw || obj->options->format_out == nsMimeOutput::nsMimeMessageBodyDisplay || obj->options->format_out == nsMimeOutput::nsMimeMessageAttach)) { // Then, check for subpart unsigned int partlen = strlen(obj->options->part_to_load); obj->output_p = (strlen(id) >= partlen + 2) && (id[partlen] == '.') && !strncmp(id, obj->options->part_to_load, partlen); } PR_Free(id); } return 0; }
/* void onStartRequest (in nsIRequest request, in nsISupports ctxt); */ NS_IMETHODIMP imgRequest::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt) { nsresult rv; LOG_SCOPE(gImgLog, "imgRequest::OnStartRequest"); NS_ASSERTION(!mDecoder, "imgRequest::OnStartRequest -- we already have a decoder"); nsCOMPtr<nsIMultiPartChannel> mpchan(do_QueryInterface(aRequest)); if (mpchan) mIsMultiPartChannel = PR_TRUE; /* * If mRequest is null here, then we need to set it so that we'll be able to * cancel it if our Cancel() method is called. Note that this can only * happen for multipart channels. We could simply not null out mRequest for * non-last parts, if GetIsLastPart() were reliable, but it's not. See * https://bugzilla.mozilla.org/show_bug.cgi?id=339610 */ if (!mRequest) { NS_ASSERTION(mpchan, "We should have an mRequest here unless we're multipart"); nsCOMPtr<nsIChannel> chan; mpchan->GetBaseChannel(getter_AddRefs(chan)); mRequest = chan; } /* set our state variables to their initial values, but advance mState to onStartRequest. */ if (mIsMultiPartChannel) { // Don't blow away our status altogether mImageStatus &= ~imgIRequest::STATUS_LOAD_PARTIAL; mImageStatus &= ~imgIRequest::STATUS_LOAD_COMPLETE; mImageStatus &= ~imgIRequest::STATUS_FRAME_COMPLETE; } else { mImageStatus = imgIRequest::STATUS_NONE; } mState = onStartRequest; nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest)); if (channel) channel->GetSecurityInfo(getter_AddRefs(mSecurityInfo)); /* set our loading flag to true */ mLoading = PR_TRUE; /* notify our kids */ nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers); while (iter.HasMore()) { iter.GetNext()->OnStartRequest(aRequest, ctxt); } /* Get our principal */ nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest)); if (chan) { nsCOMPtr<nsIScriptSecurityManager> secMan = do_GetService("@mozilla.org/scriptsecuritymanager;1"); if (secMan) { nsresult rv = secMan->GetChannelPrincipal(chan, getter_AddRefs(mPrincipal)); if (NS_FAILED(rv)) { return rv; } } } /* get the expires info */ if (mCacheEntry) { nsCOMPtr<nsICachingChannel> cacheChannel(do_QueryInterface(aRequest)); if (cacheChannel) { nsCOMPtr<nsISupports> cacheToken; cacheChannel->GetCacheToken(getter_AddRefs(cacheToken)); if (cacheToken) { nsCOMPtr<nsICacheEntryInfo> entryDesc(do_QueryInterface(cacheToken)); if (entryDesc) { PRUint32 expiration; /* get the expiration time from the caching channel's token */ entryDesc->GetExpirationTime(&expiration); /* set the expiration time on our entry */ mCacheEntry->SetExpiryTime(expiration); } } } // // Determine whether the cache entry must be revalidated when it expires. // If so, then the cache entry must *not* be used during HISTORY loads if // it has expired. // // Currently, only HTTP specifies this information... // nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aRequest)); if (httpChannel) { PRBool bMustRevalidate = PR_FALSE; rv = httpChannel->IsNoStoreResponse(&bMustRevalidate); if (!bMustRevalidate) { rv = httpChannel->IsNoCacheResponse(&bMustRevalidate); } if (!bMustRevalidate) { nsCAutoString cacheHeader; rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Cache-Control"), cacheHeader); if (PL_strcasestr(cacheHeader.get(), "must-revalidate")) { bMustRevalidate = PR_TRUE; } } mCacheEntry->SetMustValidateIfExpired(bMustRevalidate); } } // Shouldn't we be dead already if this gets hit? Probably multipart/x-mixed-replace... if (mObservers.IsEmpty()) { this->Cancel(NS_IMAGELIB_ERROR_FAILURE); } return NS_OK; }
/* caller is responsible to release "valuearray" */ int get_values_from_string(const char *string, char *type, char ***valuearray) { int rc = -1; size_t typelen = 0; char *ptr = NULL; char *copy = NULL; char *tmpptr = NULL; char *startptr = NULL; struct berval tmptype = {0, NULL}; struct berval bvvalue = {0, NULL}; int freeval = 0; char *value = NULL; int idx = 0; #define get_values_INITIALMAXCNT 1 int maxcnt = get_values_INITIALMAXCNT; if (NULL == string || NULL == type || NULL == valuearray) { return rc; } *valuearray = NULL; tmpptr = (char *)string; ptr = PL_strcasestr(tmpptr, type); if (NULL == ptr) { return rc; } typelen = strlen(type); startptr = tmpptr; while (NULL != (ptr = ldif_getline(&tmpptr))) { if ((0 != PL_strncasecmp(ptr, type, typelen)) || (*(ptr + typelen) != ';' && *(ptr + typelen) != ':')) { /* did not match */ ldif_getline_fixline(startptr, tmpptr); startptr = tmpptr; continue; } /* matched */ copy = slapi_ch_strdup(ptr); ldif_getline_fixline(startptr, tmpptr); startptr = tmpptr; rc = slapi_ldif_parse_line(copy, &tmptype, &bvvalue, &freeval); if (0 > rc || NULL == bvvalue.bv_val || 0 >= bvvalue.bv_len) { continue; } if (0 != PL_strncasecmp(type, tmptype.bv_val, tmptype.bv_len)) { char *p = PL_strchr(tmptype.bv_val, ';'); /* subtype ? */ if (p) { if (0 != strncasecmp(type, tmptype.bv_val, p - tmptype.bv_val)) { slapi_log_error(SLAPI_LOG_FATAL, "get_values_from_string", "type does not match: %s != %s\n", type, tmptype.bv_val); if (freeval) { slapi_ch_free_string(&bvvalue.bv_val); } goto bail; } } else { slapi_log_error(SLAPI_LOG_FATAL, "get_values_from_string", "type does not match: %s != %s\n", type, tmptype.bv_val); if (freeval) { slapi_ch_free_string(&bvvalue.bv_val); } goto bail; } } if (freeval) { value = bvvalue.bv_val; /* just hand off memory */ bvvalue.bv_val = NULL; } else { /* copy */ value = (char *)slapi_ch_malloc(bvvalue.bv_len + 1); memcpy(value, bvvalue.bv_val, bvvalue.bv_len); *(value + bvvalue.bv_len) = '\0'; } if ((get_values_INITIALMAXCNT == maxcnt) || !valuearray || (idx + 1 >= maxcnt)) { maxcnt *= 2; *valuearray = (char **)slapi_ch_realloc((char *)*valuearray, sizeof(char *) * maxcnt); } (*valuearray)[idx++] = value; (*valuearray)[idx] = NULL; slapi_ch_free_string(©); } bail: slapi_ch_free_string(©); return rc; }
/* caller is responsible to release "value" */ int get_value_from_string(const char *string, char *type, char **value) { int rc = -1; size_t typelen = 0; char *ptr = NULL; char *copy = NULL; char *tmpptr = NULL; char *startptr = NULL; struct berval tmptype = {0, NULL}; struct berval bvvalue = {0, NULL}; int freeval = 0; if (NULL == string || NULL == type || NULL == value) { return rc; } *value = NULL; tmpptr = (char *)string; ptr = PL_strcasestr(tmpptr, type); if (NULL == ptr) { return rc; } typelen = strlen(type); startptr = tmpptr; while (NULL != (ptr = ldif_getline(&tmpptr))) { if ((0 != PL_strncasecmp(ptr, type, typelen)) || (*(ptr + typelen) != ';' && *(ptr + typelen) != ':')) { /* did not match */ ldif_getline_fixline(startptr, tmpptr); startptr = tmpptr; continue; } /* matched */ copy = slapi_ch_strdup(ptr); ldif_getline_fixline(startptr, tmpptr); startptr = tmpptr; rc = slapi_ldif_parse_line(copy, &tmptype, &bvvalue, &freeval); if (0 > rc || NULL == tmptype.bv_val || NULL == bvvalue.bv_val || 0 >= bvvalue.bv_len) { slapi_log_error(SLAPI_LOG_FATAL, "get_value_from_string", "parse " "failed: %d\n", rc); if (freeval) { slapi_ch_free_string(&bvvalue.bv_val); } rc = -1; /* set non-0 to rc */ goto bail; } if (0 != PL_strncasecmp(type, tmptype.bv_val, tmptype.bv_len)) { slapi_log_error(SLAPI_LOG_FATAL, "get_value_from_string", "type " "does not match: %s != %s\n", type, tmptype.bv_val); if (freeval) { slapi_ch_free_string(&bvvalue.bv_val); } rc = -1; /* set non-0 to rc */ goto bail; } rc = 0; /* set 0 to rc */ if (freeval) { *value = bvvalue.bv_val; /* just hand off the memory */ bvvalue.bv_val = NULL; } else { /* make a copy */ *value = (char *)slapi_ch_malloc(bvvalue.bv_len + 1); memcpy(*value, bvvalue.bv_val, bvvalue.bv_len); *(*value + bvvalue.bv_len) = '\0'; } slapi_ch_free_string(©); } bail: slapi_ch_free_string(©); return rc; }
nsresult nsDataHandler::ParseURI(nsCString& spec, nsCString& contentType, nsCString& contentCharset, bool& isBase64, nsCString& dataBuffer, nsCString& hashRef) { isBase64 = false; // move past "data:" char *buffer = (char *) PL_strcasestr(spec.BeginWriting(), "data:"); if (!buffer) { // malformed uri return NS_ERROR_MALFORMED_URI; } buffer += 5; // First, find the start of the data char *comma = strchr(buffer, ','); if (!comma) return NS_ERROR_MALFORMED_URI; *comma = '\0'; // determine if the data is base64 encoded. char *base64 = PL_strcasestr(buffer, ";base64"); if (base64) { isBase64 = true; *base64 = '\0'; } if (comma == buffer) { // nothing but data contentType.AssignLiteral("text/plain"); contentCharset.AssignLiteral("US-ASCII"); } else { // everything else is content type char *semiColon = (char *) strchr(buffer, ';'); if (semiColon) *semiColon = '\0'; if (semiColon == buffer || base64 == buffer) { // there is no content type, but there are other parameters contentType.AssignLiteral("text/plain"); } else { contentType = buffer; ToLowerCase(contentType); } if (semiColon) { char *charset = PL_strcasestr(semiColon + 1, "charset="); if (charset) contentCharset = charset + sizeof("charset=") - 1; *semiColon = ';'; } } *comma = ','; if (isBase64) *base64 = ';'; contentType.StripWhitespace(); contentCharset.StripWhitespace(); // Split encoded data from terminal "#ref" (if present) char *data = comma + 1; char *hash = strchr(data, '#'); if (!hash) { dataBuffer.Assign(data); hashRef.Truncate(); } else { dataBuffer.Assign(data, hash - data); hashRef.Assign(hash); } return NS_OK; }
nsresult nsDataHandler::ParseURI(nsCString& spec, nsCString& contentType, nsCString* contentCharset, bool& isBase64, nsCString* dataBuffer) { isBase64 = false; // move past "data:" const char* roBuffer = (const char*) PL_strcasestr(spec.get(), "data:"); if (!roBuffer) { // malformed uri return NS_ERROR_MALFORMED_URI; } roBuffer += sizeof("data:") - 1; // First, find the start of the data const char* roComma = strchr(roBuffer, ','); const char* roHash = strchr(roBuffer, '#'); if (!roComma || (roHash && roHash < roComma)) { return NS_ERROR_MALFORMED_URI; } if (roComma == roBuffer) { // nothing but data contentType.AssignLiteral("text/plain"); if (contentCharset) { contentCharset->AssignLiteral("US-ASCII"); } } else { // Make a copy of the non-data part so we can null out parts of it as // we go. This copy will be a small number of chars, in contrast to the // data which may be large. char* buffer = PL_strndup(roBuffer, roComma - roBuffer); // determine if the data is base64 encoded. char* base64 = PL_strcasestr(buffer, BASE64_EXTENSION); if (base64) { char *beyond = base64 + sizeof(BASE64_EXTENSION) - 1; // Per the RFC 2397 grammar, "base64" MUST be at the end of the // non-data part. // // But we also allow it in between parameters so a subsequent ";" // is ok as well (this deals with *broken* data URIs, see bug // 781693 for an example). Anything after "base64" in the non-data // part will be discarded in this case, however. if (*beyond == '\0' || *beyond == ';') { isBase64 = true; *base64 = '\0'; } } // everything else is content type char *semiColon = (char *) strchr(buffer, ';'); if (semiColon) *semiColon = '\0'; if (semiColon == buffer || base64 == buffer) { // there is no content type, but there are other parameters contentType.AssignLiteral("text/plain"); } else { contentType.Assign(buffer); ToLowerCase(contentType); contentType.StripWhitespace(); } if (semiColon && contentCharset) { char *charset = PL_strcasestr(semiColon + 1, "charset="); if (charset) { contentCharset->Assign(charset + sizeof("charset=") - 1); contentCharset->StripWhitespace(); } } free(buffer); } if (dataBuffer) { // Split encoded data from terminal "#ref" (if present) const char* roData = roComma + 1; bool ok = !roHash ? dataBuffer->Assign(roData, mozilla::fallible) : dataBuffer->Assign(roData, roHash - roData, mozilla::fallible); if (!ok) { return NS_ERROR_OUT_OF_MEMORY; } } return NS_OK; }
nsresult nsDataHandler::ParseURI(nsCString& spec, nsCString& contentType, nsCString& contentCharset, bool& isBase64, nsCString& dataBuffer, nsCString& hashRef) { isBase64 = false; // move past "data:" char *buffer = (char *) PL_strcasestr(spec.BeginWriting(), "data:"); if (!buffer) { // malformed uri return NS_ERROR_MALFORMED_URI; } buffer += 5; // First, find the start of the data char *comma = strchr(buffer, ','); char *hash = strchr(buffer, '#'); if (!comma || (hash && hash < comma)) return NS_ERROR_MALFORMED_URI; *comma = '\0'; // determine if the data is base64 encoded. char *base64 = PL_strcasestr(buffer, BASE64_EXTENSION); if (base64) { char *beyond = base64 + strlen(BASE64_EXTENSION); // per the RFC 2397 grammar, "base64" MUST be followed by a comma // previously substituted by '\0', but we also allow it in between // parameters so a subsequent ";" is ok as well (this deals with // *broken* data URIs, see bug 781693 for an example) if (*beyond == '\0' || *beyond == ';') { isBase64 = true; *base64 = '\0'; } } if (comma == buffer) { // nothing but data contentType.AssignLiteral("text/plain"); contentCharset.AssignLiteral("US-ASCII"); } else { // everything else is content type char *semiColon = (char *) strchr(buffer, ';'); if (semiColon) *semiColon = '\0'; if (semiColon == buffer || base64 == buffer) { // there is no content type, but there are other parameters contentType.AssignLiteral("text/plain"); } else { contentType = buffer; ToLowerCase(contentType); } if (semiColon) { char *charset = PL_strcasestr(semiColon + 1, "charset="); if (charset) contentCharset = charset + sizeof("charset=") - 1; *semiColon = ';'; } } *comma = ','; if (isBase64) *base64 = ';'; contentType.StripWhitespace(); contentCharset.StripWhitespace(); // Split encoded data from terminal "#ref" (if present) char *data = comma + 1; if (!hash) { dataBuffer.Assign(data); hashRef.Truncate(); } else { dataBuffer.Assign(data, hash - data); hashRef.Assign(hash); } return NS_OK; }
PRBool nsMsgMdnGenerator::ProcessSendMode() { DEBUG_MDN("nsMsgMdnGenerator::ProcessSendMode"); PRInt32 miscState = 0; if (m_identity) { m_identity->GetEmail(m_email); if (m_email.IsEmpty()) return m_reallySendMdn; const char *accountDomain = strchr(m_email.get(), '@'); if (!accountDomain) return m_reallySendMdn; if (MailAddrMatch(m_email.get(), m_dntRrt.get())) // return address is self, don't send return PR_FALSE; // *** fix me see Bug 132504 for more information // *** what if the message has been filtered to different account if (!PL_strcasestr(m_dntRrt.get(), accountDomain)) miscState |= MDN_OUTSIDE_DOMAIN; if (NotInToOrCc()) miscState |= MDN_NOT_IN_TO_CC; m_reallySendMdn = PR_TRUE; // ********* // How are we gona deal with the auto forwarding issues? Some server // didn't bother to add addition header or modify existing header to // thev message when forwarding. They simply copy the exact same // message to another user's mailbox. Some change To: to // Apparently-To: // Unfortunately, there is nothing we can do. It's out of our control. // ********* // starting from lowest denominator to highest if (!miscState) { // under normal situation: recipent is in to and cc list, // and the sender is from the same domain switch (m_otherOp) { default: case eNeverSendOp: m_reallySendMdn = PR_FALSE; break; case eAutoSendOp: m_autoSend = PR_TRUE; break; case eAskMeOp: m_autoSend = PR_FALSE; break; case eDeniedOp: m_autoSend = PR_TRUE; m_disposeType = eDenied; break; } } else if (miscState == (MDN_OUTSIDE_DOMAIN | MDN_NOT_IN_TO_CC)) { if (m_outsideDomainOp != m_notInToCcOp) { m_autoSend = PR_FALSE; // ambiguous; always ask user } else { switch (m_outsideDomainOp) { default: case eNeverSendOp: m_reallySendMdn = PR_FALSE; break; case eAutoSendOp: m_autoSend = PR_TRUE; break; case eAskMeOp: m_autoSend = PR_FALSE; break; } } } else if (miscState & MDN_OUTSIDE_DOMAIN) { switch (m_outsideDomainOp) { default: case eNeverSendOp: m_reallySendMdn = PR_FALSE; break; case eAutoSendOp: m_autoSend = PR_TRUE; break; case eAskMeOp: m_autoSend = PR_FALSE; break; } } else if (miscState & MDN_NOT_IN_TO_CC) { switch (m_notInToCcOp) { default: case eNeverSendOp: m_reallySendMdn = PR_FALSE; break; case eAutoSendOp: m_autoSend = PR_TRUE; break; case eAskMeOp: m_autoSend = PR_FALSE; break; } } } return m_reallySendMdn; }
/* ///////////////////////////////////////////////////////////////////////// // actually run the installation, copying files to and fro */ static Pk11Install_Error DoInstall(JAR *jar, const char *installDir, const char *tempDir, Pk11Install_Platform *platform, PRFileDesc *feedback, PRBool noverify) { Pk11Install_File *file; Pk11Install_Error ret; char *reldir; char *dest; char *modDest; char *cp; int i; int status; char *tempname, *temp; StringList executables; StringNode *execNode; PRProcessAttr *attr; PRProcess *proc; char *argv[2]; char *envp[1]; int errcode; ret = PK11_INSTALL_UNSPECIFIED; reldir = NULL; dest = NULL; modDest = NULL; tempname = NULL; StringList_new(&executables); /* // Create Temporary directory */ tempname = PR_smprintf("%s/%s", tempDir, TEMPORARY_DIRECTORY_NAME); if (PR_Access(tempname, PR_ACCESS_EXISTS) == PR_SUCCESS) { /* Left over from previous run? Delete it. */ rm_dash_r(tempname); } if (PR_MkDir(tempname, 0700) != PR_SUCCESS) { error(PK11_INSTALL_CREATE_DIR, tempname); ret = PK11_INSTALL_CREATE_DIR; goto loser; } /* // Install all the files */ for (i = 0; i < platform->numFiles; i++) { file = &platform->files[i]; if (file->relativePath) { PRBool foundMarker = PR_FALSE; reldir = PR_Strdup(file->relativePath); /* Replace all the markers with the directories for which they stand */ while (1) { if ((cp = PL_strcasestr(reldir, ROOT_MARKER))) { /* Has a %root% marker */ *cp = '\0'; temp = PR_smprintf("%s%s%s", reldir, installDir, cp + strlen(ROOT_MARKER)); PR_Free(reldir); reldir = temp; foundMarker = PR_TRUE; } else if ((cp = PL_strcasestr(reldir, TEMP_MARKER))) { /* Has a %temp% marker */ *cp = '\0'; temp = PR_smprintf("%s%s%s", reldir, tempname, cp + strlen(TEMP_MARKER)); PR_Free(reldir); reldir = temp; foundMarker = PR_TRUE; } else { break; } } if (!foundMarker) { /* Has no markers...this isn't really a relative directory */ error(PK11_INSTALL_BOGUS_REL_DIR, file->relativePath); ret = PK11_INSTALL_BOGUS_REL_DIR; goto loser; } dest = reldir; reldir = NULL; } else if (file->absolutePath) { dest = PR_Strdup(file->absolutePath); } /* Remember if this is the module file, we'll need to add it later */ if (i == platform->modFile) { modDest = PR_Strdup(dest); } /* Remember is this is an executable, we'll need to run it later */ if (file->executable) { StringList_Append(&executables, dest); /*executables.Append(dest);*/ } /* Make sure the directory we are targetting exists */ if (make_dirs(dest, file->permissions)) { ret = PK11_INSTALL_CREATE_DIR; goto loser; } /* Actually extract the file onto the filesystem */ if (noverify) { status = JAR_extract(jar, (char *)file->jarPath, dest); } else { status = JAR_verified_extract(jar, (char *)file->jarPath, dest); } if (status) { if (status >= JAR_BASE && status <= JAR_BASE_END) { error(PK11_INSTALL_JAR_EXTRACT, file->jarPath, JAR_get_error(status)); } else { error(PK11_INSTALL_JAR_EXTRACT, file->jarPath, mySECU_ErrorString(PORT_GetError())); } ret = PK11_INSTALL_JAR_EXTRACT; goto loser; } if (feedback) { PR_fprintf(feedback, msgStrings[INSTALLED_FILE_MSG], file->jarPath, dest); } /* no NSPR command to change permissions? */ #ifdef XP_UNIX chmod(dest, file->permissions); #endif /* Memory clean-up tasks */ if (reldir) { PR_Free(reldir); reldir = NULL; } if (dest) { PR_Free(dest); dest = NULL; } } /* Make sure we found the module file */ if (!modDest) { /* Internal problem here, since every platform is supposed to have a module file */ error(PK11_INSTALL_NO_MOD_FILE, platform->moduleName); ret = PK11_INSTALL_NO_MOD_FILE; goto loser; } /* // Execute any executable files */ { argv[1] = NULL; envp[0] = NULL; for (execNode = executables.head; execNode; execNode = execNode->next) { attr = PR_NewProcessAttr(); argv[0] = PR_Strdup(execNode->str); /* Announce our intentions */ if (feedback) { PR_fprintf(feedback, msgStrings[EXEC_FILE_MSG], execNode->str); } /* start the process */ if (!(proc = PR_CreateProcess(execNode->str, argv, envp, attr))) { PR_Free(argv[0]); PR_DestroyProcessAttr(attr); error(PK11_INSTALL_EXEC_FILE, execNode->str); ret = PK11_INSTALL_EXEC_FILE; goto loser; } /* wait for it to finish */ if (PR_WaitProcess(proc, &errcode) != PR_SUCCESS) { PR_Free(argv[0]); PR_DestroyProcessAttr(attr); error(PK11_INSTALL_WAIT_PROCESS, execNode->str); ret = PK11_INSTALL_WAIT_PROCESS; goto loser; } /* What happened? */ if (errcode) { /* process returned an error */ error(PK11_INSTALL_PROC_ERROR, execNode->str, errcode); } else if (feedback) { /* process ran successfully */ PR_fprintf(feedback, msgStrings[EXEC_SUCCESS], execNode->str); } PR_Free(argv[0]); PR_DestroyProcessAttr(attr); } } /* // Add the module */ status = Pk11Install_AddNewModule((char *)platform->moduleName, (char *)modDest, platform->mechFlags, platform->cipherFlags); if (status != SECSuccess) { error(PK11_INSTALL_ADD_MODULE, platform->moduleName); ret = PK11_INSTALL_ADD_MODULE; goto loser; } if (feedback) { PR_fprintf(feedback, msgStrings[INSTALLED_MODULE_MSG], platform->moduleName); } if (feedback) { PR_fprintf(feedback, msgStrings[INSTALLATION_COMPLETE_MSG]); } ret = PK11_INSTALL_SUCCESS; loser: if (reldir) { PR_Free(reldir); } if (dest) { PR_Free(dest); } if (modDest) { PR_Free(modDest); } if (tempname) { PRFileInfo info; if (PR_GetFileInfo(tempname, &info) == PR_SUCCESS) { if (info.type == PR_FILE_DIRECTORY) { /* Recursively remove temporary directory */ if (rm_dash_r(tempname)) { error(PK11_INSTALL_REMOVE_DIR, tempname); ret = PK11_INSTALL_REMOVE_DIR; } } } PR_Free(tempname); } StringList_delete(&executables); return ret; }
nsresult nsHttpConnection::OnHeadersAvailable(nsAHttpTransaction *trans, nsHttpRequestHead *requestHead, nsHttpResponseHead *responseHead, PRBool *reset) { LOG(("nsHttpConnection::OnHeadersAvailable [this=%p trans=%p response-head=%p]\n", this, trans, responseHead)); NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread"); NS_ENSURE_ARG_POINTER(trans); NS_ASSERTION(responseHead, "No response head?"); // If the server issued an explicit timeout, then we need to close down the // socket transport. We pass an error code of NS_ERROR_NET_RESET to // trigger the transactions 'restart' mechanism. We tell it to reset its // response headers so that it will be ready to receive the new response. if (responseHead->Status() == 408) { Close(NS_ERROR_NET_RESET); *reset = PR_TRUE; return NS_OK; } // we won't change our keep-alive policy unless the server has explicitly // told us to do so. // inspect the connection headers for keep-alive info provided the // transaction completed successfully. const char *val = responseHead->PeekHeader(nsHttp::Connection); if (!val) val = responseHead->PeekHeader(nsHttp::Proxy_Connection); // reset to default (the server may have changed since we last checked) mSupportsPipelining = PR_FALSE; if ((responseHead->Version() < NS_HTTP_VERSION_1_1) || (requestHead->Version() < NS_HTTP_VERSION_1_1)) { // HTTP/1.0 connections are by default NOT persistent if (val && !PL_strcasecmp(val, "keep-alive")) mKeepAlive = PR_TRUE; else mKeepAlive = PR_FALSE; } else { // HTTP/1.1 connections are by default persistent if (val && !PL_strcasecmp(val, "close")) mKeepAlive = PR_FALSE; else { mKeepAlive = PR_TRUE; // Do not support pipelining when we are establishing // an SSL tunnel though an HTTP proxy. Pipelining support // determination must be based on comunication with the // target server in this case. See bug 422016 for futher // details. if (!mSSLProxyConnectStream) mSupportsPipelining = SupportsPipelining(responseHead); } } mKeepAliveMask = mKeepAlive; // if this connection is persistent, then the server may send a "Keep-Alive" // header specifying the maximum number of times the connection can be // reused as well as the maximum amount of time the connection can be idle // before the server will close it. we ignore the max reuse count, because // a "keep-alive" connection is by definition capable of being reused, and // we only care about being able to reuse it once. if a timeout is not // specified then we use our advertized timeout value. if (mKeepAlive) { val = responseHead->PeekHeader(nsHttp::Keep_Alive); const char *cp = PL_strcasestr(val, "timeout="); if (cp) mIdleTimeout = (PRUint32) atoi(cp + 8); else mIdleTimeout = gHttpHandler->IdleTimeout(); LOG(("Connection can be reused [this=%x idle-timeout=%u]\n", this, mIdleTimeout)); } // if we're doing an SSL proxy connect, then we need to check whether or not // the connect was successful. if so, then we have to reset the transaction // and step-up the socket connection to SSL. finally, we have to wake up the // socket write request. if (mSSLProxyConnectStream) { mSSLProxyConnectStream = 0; if (responseHead->Status() == 200) { LOG(("SSL proxy CONNECT succeeded!\n")); *reset = PR_TRUE; nsresult rv = ProxyStartSSL(); if (NS_FAILED(rv)) // XXX need to handle this for real LOG(("ProxyStartSSL failed [rv=%x]\n", rv)); mCompletedSSLConnect = PR_TRUE; rv = mSocketOut->AsyncWait(this, 0, 0, nsnull); // XXX what if this fails -- need to handle this error NS_ASSERTION(NS_SUCCEEDED(rv), "mSocketOut->AsyncWait failed"); } else { LOG(("SSL proxy CONNECT failed!\n")); // NOTE: this cast is valid since this connection cannot be // processing a transaction pipeline until after the first HTTP/1.1 // response. nsHttpTransaction *trans = static_cast<nsHttpTransaction *>(mTransaction); trans->SetSSLConnectFailed(); } } return NS_OK; }