int MaEgiHandler::run(MaRequest *rq) { MaEgiForm *form; MaDataStream *dynBuf; MaHeader *header; char *uri; int flags; flags = rq->getFlags(); if (flags & MPR_HTTP_POST_REQUEST && rq->getRemainingContent() > 0) { // // When all the post data is received the run method will be recalled // by the postData method. // header = rq->getHeader(); if (mprStrCmpAnyCase(header->contentMimeType, "application/x-www-form-urlencoded") == 0) { egiFlags |= MPR_EGI_URL_ENCODED; } return MPR_HTTP_HANDLER_FINISHED_PROCESSING; } hitCount++; rq->setResponseCode(200); rq->setResponseMimeType("text/html"); rq->setHeaderFlags(MPR_HTTP_DONT_CACHE, 0); rq->insertDataStream(rq->getDynBuf()); uri = rq->getUri(); mprLog(4, log, "%d: serving: %s\n", rq->getFd(), uri); form = (MaEgiForm*) forms->lookup(uri); if (form == 0) { rq->requestError(404, "EGI Form: \"%s\" is not defined", uri); rq->finishRequest(); } else { form->run(rq, uri, rq->getOriginalUri(), rq->getQueryString(), postBuf->getStart(), postBuf->getLength()); if (rq->getState() == MPR_HTTP_RUNNING) { dynBuf = rq->getDynBuf(); // // This flag is only used by the GoAhead compatibility layer. // Users needing this functionality should create their own // custom handler // if (rq->getFlags() & MPR_HTTP_DONT_FINISH) { rq->flushOutput(MPR_HTTP_BACKGROUND_FLUSH, 0); } else { rq->flushOutput(MPR_HTTP_BACKGROUND_FLUSH, MPR_HTTP_FINISH_REQUEST); } } } return MPR_HTTP_HANDLER_FINISHED_PROCESSING; }
int MaCgiHandler::parseConfig(char *key, char *value, MaServer *server, MaHost *host, MaAuth *auth, MaDir *dir, MaLocation *location) { char *program, *mimeType; if (mprStrCmpAnyCase(key, "Action") == 0) { if (server->splitValue(&mimeType, &program, value, 1) < 0) { return MPR_ERR_BAD_SYNTAX; } host->setMimeActionProgram(mimeType, program); return 1; } return 0; }
static char *getHive(char *keyPath, HKEY *hive) { char key[MPR_MAX_STRING], *cp; int len; mprAssert(keyPath && *keyPath); *hive = 0; mprStrcpy(key, sizeof(key), keyPath); key[sizeof(key) - 1] = '\0'; if (cp = strchr(key, '\\')) { *cp++ = '\0'; } if (cp == 0 || *cp == '\0') { return 0; } if (!mprStrCmpAnyCase(key, "HKEY_LOCAL_MACHINE")) { *hive = HKEY_LOCAL_MACHINE; } else if (!mprStrCmpAnyCase(key, "HKEY_CURRENT_USER")) { *hive = HKEY_CURRENT_USER; } else if (!mprStrCmpAnyCase(key, "HKEY_USERS")) { *hive = HKEY_USERS; } else if (!mprStrCmpAnyCase(key, "HKEY_CLASSES_ROOT")) { *hive = HKEY_CLASSES_ROOT; } else { mprError(MPR_L, MPR_LOG, "Bad hive key: %s", key); } if (*hive == 0) { return 0; } len = strlen(key) + 1; return keyPath + len; }
static int fetch(MaClient *client, char *method, char *url, char *data, int len) { struct stat sbuf; FILE *fp; MaUrl *parsedUrl; char *header, *content, *diffBuf, *msg; char path[MPR_MAX_PATH], dir[MPR_MAX_PATH], urlBuf[MPR_HTTP_MAX_URL]; char tmp[MPR_MAX_PATH]; int i, code, rc, contentLen, mark, elapsed, c; fp = 0; lock(); fetchCount++; unlock(); if (url == 0) { return MPR_ERR_BAD_ARGS; } if (*url == '/') { mprSprintf(urlBuf, sizeof(urlBuf), "http://127.0.0.1%s", url); url = urlBuf; } else if ((strstr(url, "http://")) == 0) { mprSprintf(urlBuf, sizeof(urlBuf), "http://%s", url); url = urlBuf; } mprLog(MPR_DEBUG, tMod, "fetch: %s %s\n", method, url); mark = mprGetTime(0); if (mprStrCmpAnyCase(method, "GET") == 0) { rc = client->getRequest(url); } else if (mprStrCmpAnyCase(method, "HEAD") == 0) { rc = client->headRequest(url); } else if (mprStrCmpAnyCase(method, "OPTIONS") == 0) { rc = client->optionsRequest(url); } else if (mprStrCmpAnyCase(method, "POST") == 0) { rc = client->postRequest(url, data, len); } else if (mprStrCmpAnyCase(method, "TRACE") == 0) { rc = client->traceRequest(url); } if (rc < 0) { return MPR_ERR_CANT_OPEN; } code = client->getResponseCode(); content = client->getResponseContent(&contentLen); header = client->getResponseHeader(); msg = client->getResponseMessage(); elapsed = mprGetTime(0) - mark; if (code == 200 || code == 302) { mprLog(6, tMod, "Response code %d, content len %d, header: \n%s\n", code, contentLen, header); } else { mprLog(2, tMod, "Response code %d, content len %d, header: \n%s\n%s", code, contentLen, header, content); mprError(MPR_L, MPR_USER, "Can't retrieve \"%s\" (%d), %s", url, code, msg); return MPR_ERR_CANT_READ; } if (cmpDir) { client->getParsedUrl(&parsedUrl); mprSprintf(path, sizeof(path), "%s%s", cmpDir, parsedUrl->uri); if (path[strlen(path) - 1] == '/') { path[strlen(path) - 1] = '\0'; } if (stat(path, &sbuf) < 0) { mprError(MPR_L, MPR_USER, "Can't access %s", path); return MPR_ERR_CANT_ACCESS; } if (sbuf.st_mode & S_IFDIR) { strcpy(tmp, path); mprSprintf(path, sizeof(path), "%s/_DEFAULT_.html", tmp); } if (stat(path, &sbuf) < 0) { mprError(MPR_L, MPR_USER, "Can't access %s", path); return MPR_ERR_CANT_ACCESS; } if ((int) sbuf.st_size != contentLen) { mprError(MPR_L, MPR_USER, "Failed comparison for %s" "ContentLen %d, size %d\n", url, contentLen, sbuf.st_size); return MPR_ERR_CANT_ACCESS; } if ((fp = fopen(path, "r" MPR_BINARY)) == 0) { mprError(MPR_L, MPR_USER, "Can't open %s", path); return MPR_ERR_CANT_OPEN; } diffBuf = (char*) mprMalloc(contentLen); if ((int) fread(diffBuf, 1, contentLen, fp) != contentLen) { mprError(MPR_L, MPR_USER, "Can't read content from %s", path); return MPR_ERR_CANT_READ; } for (i = 0; i < contentLen; i++) { if (diffBuf[i] != content[i]) { mprError(MPR_L, MPR_USER, "Failed comparison for %s" "At byte %d: %x vs %x\n", i, (uchar) diffBuf[i], (uchar) content[i]); return MPR_ERR_GENERAL; } } fclose(fp); mprFree(diffBuf); } if (writeDir) { client->getParsedUrl(&parsedUrl); mprSprintf(path, sizeof(path), "%s%s", writeDir, parsedUrl->uri); if (path[strlen(path) - 1] == '/') { path[strlen(path) - 1] = '\0'; } mprGetDirName(dir, sizeof(dir), path); mprMakeDir(dir); if (stat(path, &sbuf) == 0 && sbuf.st_mode & S_IFDIR) { strcpy(tmp, path); mprSprintf(path, sizeof(path), "%s/_DEFAULT_.html", tmp); } if ((fp = fopen(path, "w" MPR_BINARY)) == 0) { mprError(MPR_L, MPR_USER, "Can't open %s", path); return MPR_ERR_CANT_OPEN; } if (outputHeader) { if (fputs(header, fp) != EOF) { mprError(MPR_L, MPR_USER, "Can't write header to %s", path); return MPR_ERR_CANT_WRITE; } fputc('\n', fp); } if ((int) fwrite(content, 1, contentLen, fp) != contentLen) { mprError(MPR_L, MPR_USER, "Can't write content to %s", path); return MPR_ERR_CANT_WRITE; } fclose(fp); } lock(); if (trace) { if (strstr(url, "http://") != 0) { url += 7; } if ((fetchCount % 100) == 1) { if (fetchCount == 1 || (fetchCount % 2500) == 1) { if (fetchCount > 1) { mprPrintf("\n"); } mprPrintf( " Count Fd Thread Op Code Bytes Time Url\n"); } mprPrintf("%8d %4d %7s %4s %5d %7d %5.2f %s\n", fetchCount - 1, client->getFd(), #if BLD_FEATURE_MULTITHREAD mprGetCurrentThreadName(), #else "", #endif method, code, contentLen, elapsed / 1000.0, url); } } if (outputHeader) { mprPrintf("%s\n", header); } if (!quietMode) { for (i = 0; i < contentLen; i++) { if (!isprint((uchar) content[i]) && content[i] != '\n' && content[i] != '\r' && content[i] != '\t') { break; } } if (contentLen > 0) { if (i != contentLen && 0) { mprPrintf("Content has non-printable data\n"); } else { // mprPrintf("Length of content %d\n", contentLen); for (i = 0; i < contentLen; i++) { c = (uchar) content[i]; if (isprint((uchar) c) || isspace((uchar) c)) { putchar(content[i]); } else { mprPrintf("0x%x", c); } } fflush(stdout); } } } unlock(); if (singleStep) { mprPrintf("Pause: "); read(0, (char*) &rc, 1); } return 0; }
int MaSslModule::parseConfig(char *key, char *value, MaServer *server, MaHost *host, MaAuth *auth, MaDir *dir, MaLocation *location) { MaSslConfig *config; char pathBuf[MPR_MAX_FNAME], prefix[MPR_MAX_FNAME]; char *tok, *word, *enable, *provider; int protoMask, mask; mprStrcpy(prefix, sizeof(prefix), key); prefix[3] = '\0'; if (mprStrCmpAnyCase(prefix, "SSL") != 0) { return 0; } if (mprStrCmpAnyCase(key, "SSLEngine") == 0) { enable = mprStrTok(value, " \t", &tok); provider = mprStrTok(0, " \t", &tok); if (mprStrCmpAnyCase(value, "on") == 0) { if (sslProvider == 0) { mprError(MPR_L, MPR_LOG, "Missing an SSL Provider\n"); return MPR_ERR_BAD_SYNTAX; } config = (MaSslConfig*) sslConfigTable->lookup(host->getName()); if (config == 0) { config = sslProvider->newConfig(host); mprAssert(config); sslConfigTable->insert(config); } host->setSecure(1); host->server->setSslListeners(host, config); } return 1; } config = (MaSslConfig*) sslConfigTable->lookup(host->getName()); if (config == 0) { mprError(MPR_L, MPR_LOG, "Missing SSLEngine directive\n"); return MPR_ERR_BAD_SYNTAX; } if (host->makePath(pathBuf, sizeof(pathBuf), mprStrTrim(value, '\"')) == 0) { mprError(MPR_L, MPR_LOG, "SSL path is too long"); return MPR_ERR_BAD_SYNTAX; } if (mprStrCmpAnyCase(key, "SSLCACertificatePath") == 0) { config->setCaPath(pathBuf); return 1; } else if (mprStrCmpAnyCase(key, "SSLCACertificateFile") == 0) { config->setCaFile(pathBuf); return 1; } else if (mprStrCmpAnyCase(key, "SSLCertificateFile") == 0) { config->setCertFile(pathBuf); return 1; } else if (mprStrCmpAnyCase(key, "SSLCertificateKeyFile") == 0) { config->setKeyFile(pathBuf); return 1; } else if (mprStrCmpAnyCase(key, "SSLCipherSuite") == 0) { config->setCipherSuite(value); return 1; } else if (mprStrCmpAnyCase(key, "SSLVerifyClient") == 0) { if (mprStrCmpAnyCase(value, "require") == 0) { config->setVerifyClient(1); } else if (mprStrCmpAnyCase(value, "none") == 0) { config->setVerifyClient(0); } else { return -1; } return 1; } else if (mprStrCmpAnyCase(key, "SSLProtocol") == 0) { protoMask = 0; word = mprStrTok(value, " \t", &tok); while (word) { mask = -1; if (*word == '-') { word++; mask = 0; } else if (*word == '+') { word++; } if (mprStrCmpAnyCase(word, "SSLv2") == 0) { protoMask &= ~(MPR_HTTP_PROTO_SSLV2 & ~mask); protoMask |= (MPR_HTTP_PROTO_SSLV2 & mask); } else if (mprStrCmpAnyCase(word, "SSLv3") == 0) { protoMask &= ~(MPR_HTTP_PROTO_SSLV3 & ~mask); protoMask |= (MPR_HTTP_PROTO_SSLV3 & mask); } else if (mprStrCmpAnyCase(word, "TLSv1") == 0) { protoMask &= ~(MPR_HTTP_PROTO_TLSV1 & ~mask); protoMask |= (MPR_HTTP_PROTO_TLSV1 & mask); } else if (mprStrCmpAnyCase(word, "ALL") == 0) { protoMask &= ~(MPR_HTTP_PROTO_ALL & ~mask); protoMask |= (MPR_HTTP_PROTO_ALL & mask); } word = mprStrTok(0, " \t", &tok); } config->setSslProto(protoMask); return 1; } return 0; }
int MaClient::parseHeader(char *line) { char *key, *value, *tok, *tp; mprAssert(line && *line); if ((key = mprStrTok(line, ": \t\n", &tok)) == 0) { formatError("Bad HTTP header"); responseCode = MPR_HTTP_CLIENT_ERROR; finishRequest(1); return MPR_ERR_BAD_STATE; } if ((value = mprStrTok(0, "\n", &tok)) == 0) { value = ""; } while (isspace((uchar) *value)) { value++; } // Upper to be consistent with Request? mprStrLower(key); headerValues->insert(new MprStringHashEntry(key, value)); if (strcmp("www-authenticate", key) == 0) { tp = value; while (*value && !isspace((uchar) *value)) { value++; } *value++ = '\0'; mprStrLower(tp); mprFree(serverAuthType); serverAuthType = mprStrdup(tp); if (parseAuthenticate(value) < 0) { formatError("Bad Authenticate header"); responseCode = MPR_HTTP_CLIENT_ERROR; finishRequest(1); return MPR_ERR_BAD_STATE; } } else if (strcmp("content-length", key) == 0) { contentLength = atoi(value); if (mprStrCmpAnyCase(method, "HEAD") != 0) { contentRemaining = atoi(value); } } else if (strcmp("connection", key) == 0) { mprStrLower(value); if (strcmp(value, "close") == 0) { flags &= ~MPR_HTTP_KEEP_ALIVE; #if BLD_FEATURE_KEEP_ALIVE } else if (strcmp(value, "keep-alive") == 0) { if (userFlags & MPR_HTTP_KEEP_ALIVE) { flags |= MPR_HTTP_KEEP_ALIVE; } #endif } } else if (strcmp("transfer-encoding", key) == 0) { mprStrLower(value); if (strcmp(value, "chunked") == 0) { flags |= MPR_HTTP_INPUT_CHUNKED; } } return 0; }
int MaClient::processResponseData() { char *line, *cp; int nbytes; mprLog(6, tMod, "READ DATA: %s\n", inBuf->getStart()); timestamp = mprGetTime(0); line = 0; while (state != MPR_HTTP_CLIENT_DONE && inBuf->getLength() > 0) { line = inBuf->getStart(); if (state != MPR_HTTP_CLIENT_CONTENT) { if ((cp = strchr(line, '\n')) == 0) { // Wait for more data return 0; } *cp = '\0'; if (cp[-1] == '\r') { nbytes = cp - line; *--cp = '\0'; } else { nbytes = cp - line; } inBuf->adjustStart(nbytes + 1); } else { if (contentLength <= 0) { nbytes = inBuf->getLength(); } else { nbytes = min(contentRemaining, inBuf->getLength()); } inBuf->adjustStart(nbytes); } switch(state) { case MPR_HTTP_CLIENT_START: mprLog(3, tMod, "processResponseData: %s\n", line); if (line[0] == '\0') { return 0; } responseHeader->put(line); responseHeader->put('\n'); if (parseFirst(line) < 0) { return MPR_ERR_BAD_STATE; } state = MPR_HTTP_CLIENT_HEADER; break; case MPR_HTTP_CLIENT_HEADER: if (nbytes > 1) { mprLog(3, tMod, "processResponseData: %s\n", line); responseHeader->put(line); responseHeader->put('\n'); if (parseHeader(line) < 0) { return MPR_ERR_BAD_STATE; } } else { // // Blank line means end of headers // if (flags & MPR_HTTP_INPUT_CHUNKED) { if (flags & MPR_HTTP_END_CHUNK_DATA) { finishRequest(0); } else { state = MPR_HTTP_CLIENT_CHUNK; } } else { state = MPR_HTTP_CLIENT_CONTENT; // // This means there was an explicit zero content length // if (contentRemaining == 0) { finishRequest(0); } else if (mprStrCmpAnyCase(method, "HEAD") == 0) { finishRequest(0); } } } break; case MPR_HTTP_CLIENT_CHUNK: mprLog(3, tMod, "processResponseData: %s\n", line); contentRemaining = contentLength = mprAtoi(line, 16); if (contentLength <= 0) { flags |= MPR_HTTP_END_CHUNK_DATA; state = MPR_HTTP_CLIENT_HEADER; } else { state = MPR_HTTP_CLIENT_CONTENT; } if (contentLength > MPR_HTTP_CLIENT_BUFSIZE) { delete responseContent; responseContent = new MprBuf(contentLength + 1, -1); } break; case MPR_HTTP_CLIENT_CONTENT: responseContent->put((uchar*) line, nbytes); responseContent->addNull(); mprLog(3, tMod, "processResponseData: %d bytes, %d remaining, %d sofar\n", nbytes, contentRemaining, responseContent->getLength()); if (contentRemaining > 0 || nbytes <= 0) { contentRemaining -= nbytes; if (contentRemaining <= 0) { /* if (!(flags & MPR_HTTP_INPUT_CHUNKED)) */ finishRequest(0); } } break; default: formatError("Bad state"); responseCode = MPR_HTTP_CLIENT_ERROR; finishRequest(1); return MPR_ERR_BAD_STATE; } } return 0; }
int MaClient::sendCore(char *method, char *requestUrl, char *postData, int postLen) { char abuf[MPR_HTTP_MAX_PASS * 2], encDetails[MPR_HTTP_MAX_PASS * 2]; char *host; int port, len, rc, nbytes; mprAssert(requestUrl && *requestUrl); lock(); reset(); mprLog(3, tMod, "sendCore: %s %s\n", method, requestUrl); this->method = mprStrdup(method); timestamp = mprGetTime(0); if (timeoutPeriod < 0) { timeoutPeriod = MPR_HTTP_CLIENT_TIMEOUT; } if (timeoutPeriod > 0) { if (!mprGetDebugMode()) { timer = new MprTimer(MPR_HTTP_TIMER_PERIOD, timeoutWrapper, (void *) this); } } if (*requestUrl == '/') { url.parse(requestUrl); host = (proxyHost) ? proxyHost : defaultHost; port = (proxyHost) ? proxyPort : defaultPort; } else { url.parse(requestUrl); host = (proxyHost) ? proxyHost : url.host; port = (proxyHost) ? proxyPort : url.port; } if (sock) { if (port != currentPort || strcmp(host, currentHost) != 0) { // // This request is for a different host or port. Must close socket. // sock->close(0); sock->dispose(); sock = 0; } } if (sock == 0) { sock = new MprSocket(); mprLog(3, tMod, "Opening new socket on: %s:%d\n", host, port); rc = sock->openClient(host, port, MPR_SOCKET_NODELAY); if (rc < 0) { mprLog(MPR_ERROR, tMod, "Can't open socket on %s:%d, %d\n", host, port, rc); unlock(); sock->dispose(); sock = 0; return rc; } sock->setBufSize(-1, MPR_HTTP_CLIENT_BUFSIZE); currentHost = mprStrdup(host); currentPort = port; } else { mprLog(3, tMod, "Reusing Keep-Alive socket on: %s:%d\n", host, port); } // // Remove this flush when pipelining is supported // inBuf->flush(); fd = sock->getFd(); if (proxyHost && *proxyHost) { if (url.query && *url.query) { outBuf->putFmt("%s http://%s:%d%s?%s HTTP/1.1\r\n", method, proxyHost, proxyPort, url.uri, url.query); } else { outBuf->putFmt("%s http://%s:%d%s HTTP/1.1\r\n", method, proxyHost, proxyPort, url.uri); } } else { if (url.query && *url.query) { outBuf->putFmt("%s %s?%s HTTP/1.1\r\n", method, url.uri, url.query); } else { outBuf->putFmt("%s %s HTTP/1.1\r\n", method, url.uri); } } if (serverAuthType) { if (strcmp(serverAuthType, "basic") == 0) { mprSprintf(abuf, sizeof(abuf), "%s:%s", user, password); maEncode64(encDetails, sizeof(encDetails), abuf); outBuf->putFmt("Authorization: %s %s\r\n", serverAuthType, encDetails); #if BLD_FEATURE_DIGEST } else if (strcmp(serverAuthType, "digest") == 0) { char a1Buf[256], a2Buf[256], digestBuf[256]; char *ha1, *ha2, *digest, *qop; authNc++; if (secret == 0) { if (createSecret() < 0) { mprLog(MPR_ERROR, tMod, "Can't create secret\n"); return MPR_ERR_CANT_INITIALIZE; } } mprFree(authCnonce); maCalcNonce(&authCnonce, secret, 0, realm); mprSprintf(a1Buf, sizeof(a1Buf), "%s:%s:%s", user, realm, password); ha1 = maMD5(a1Buf); mprSprintf(a2Buf, sizeof(a2Buf), "%s:%s", method, url.uri); ha2 = maMD5(a2Buf); qop = (serverQop) ? serverQop : (char*) ""; if (mprStrCmpAnyCase(serverQop, "auth") == 0) { mprSprintf(digestBuf, sizeof(digestBuf), "%s:%s:%08x:%s:%s:%s", ha1, serverNonce, authNc, authCnonce, serverQop, ha2); } else if (mprStrCmpAnyCase(serverQop, "auth-int") == 0) { mprSprintf(digestBuf, sizeof(digestBuf), "%s:%s:%08x:%s:%s:%s", ha1, serverNonce, authNc, authCnonce, serverQop, ha2); } else { qop = ""; mprSprintf(digestBuf, sizeof(digestBuf), "%s:%s:%s", ha1, serverNonce, ha2); } mprFree(ha1); mprFree(ha2); digest = maMD5(digestBuf); if (*qop == '\0') { outBuf->putFmt("Authorization: Digest " "username=\"%s\", realm=\"%s\", nonce=\"%s\", " "uri=\"%s\", response=\"%s\"\r\n", user, realm, serverNonce, url.uri, digest); } else if (strcmp(qop, "auth") == 0) { outBuf->putFmt("Authorization: Digest " "username=\"%s\", realm=\"%s\", domain=\"%s\", " "algorithm=\"MD5\", qop=\"%s\", cnonce=\"%s\", " "nc=\"%08x\", nonce=\"%s\", opaque=\"%s\", " "stale=\"FALSE\", uri=\"%s\", response=\"%s\"\r\n", user, realm, serverDomain, serverQop, authCnonce, authNc, serverNonce, serverOpaque, url.uri, digest); } else if (strcmp(qop, "auth-int") == 0) { ; } mprFree(digest); #endif // BLD_FEATURE_HTTP_DIGEST } } outBuf->putFmt("Host: %s\r\n", host); outBuf->putFmt("User-Agent: %s\r\n", MPR_HTTP_CLIENT_NAME); if (userFlags & MPR_HTTP_KEEP_ALIVE) { outBuf->putFmt("Connection: Keep-Alive\r\n"); } else { outBuf->putFmt("Connection: close\r\n"); } if (postLen > 0) { outBuf->putFmt("Content-Length: %d\r\n", postLen); } if (postData) { outBuf->putFmt("Content-Type: application/x-www-form-urlencoded\r\n"); } if (userHeaders) { outBuf->put(userHeaders); } outBuf->put("\r\n"); outBuf->addNull(); // // Flush to the socket with any post data. Writes can fail because the // server prematurely closes a keep-alive connection. // len = outBuf->getLength(); if ((rc = sock->write(outBuf->getStart(), len)) != len) { flags |= MPR_HTTP_TERMINATED; unlock(); mprLog(MPR_ERROR, tMod, "Can't write to socket on %s:%d, %d\n", host, port, rc); return rc; } #if BLD_DEBUG mprLog(3, MPR_RAW, tMod, "Request >>>>\n%s\n", outBuf->getStart()); #endif if (postData) { sock->setBlockingMode(1); for (len = 0; len < postLen; ) { nbytes = postLen - len; rc = sock->write(&postData[len], nbytes); #if BLD_DEBUG mprLog(3, MPR_RAW, tMod, "POST DATA %s\n", &postData[len]); #endif if (rc < 0) { unlock(); mprLog(MPR_ERROR, tMod, "Can't write post data to socket on %s:%d, %d\n", host, port, rc); flags |= MPR_HTTP_TERMINATED; sock->dispose(); sock = 0; return rc; } len += rc; } sock->setBlockingMode(0); } sock->setCallback(readEventWrapper, (void*) this, 0, MPR_READABLE); // // If no callback, then we must block // if (callback == 0) { unlock(); while (state != MPR_HTTP_CLIENT_DONE) { // // If multithreaded and the events thread is not yet running, // we still want to work. // #if BLD_FEATURE_MULTITHREAD if (mprGetMpr()->isRunningEventsThread() && mprGetMpr()->poolService->getMaxPoolThreads() > 0) { completeCond->waitForCond(250); } else #endif mprGetMpr()->serviceEvents(1, 100); } } else { unlock(); } return 0; }
int MaClient::parseAuthenticate(char *authDetails) { char *value, *tok, *key, *dp, *sp; int seenComma; key = authDetails; while (*key) { while (*key && isspace((uchar) *key)) { key++; } tok = key; while (*tok && !isspace((uchar) *tok) && *tok != ',' && *tok != '=') { tok++; } *tok++ = '\0'; while (isspace((uchar) *tok)) { tok++; } seenComma = 0; if (*tok == '\"') { value = ++tok; while (*tok != '\"' && *tok != '\0') { tok++; } } else { value = tok; while (*tok != ',' && *tok != '\0') { tok++; } seenComma++; } *tok++ = '\0'; // // Handle back-quoting // if (strchr(value, '\\')) { for (dp = sp = value; *sp; sp++) { if (*sp == '\\') { sp++; } *dp++ = *sp++; } *dp = '\0'; } // // algorithm, domain, nonce, oqaque, realm, qop, stale // switch (tolower((uchar) *key)) { case 'a': if (mprStrCmpAnyCase(key, "algorithm") == 0) { mprFree(serverAlgorithm); serverAlgorithm = mprStrdup(value); break; // } else if (mprStrCmpAnyCase(key, "server-param") == 0) { // break; } break; case 'd': if (mprStrCmpAnyCase(key, "domain") == 0) { mprFree(serverDomain); serverDomain = mprStrdup(value); break; } break; case 'n': if (mprStrCmpAnyCase(key, "nonce") == 0) { mprFree(serverNonce); serverNonce = mprStrdup(value); authNc = 0; } break; case 'o': if (mprStrCmpAnyCase(key, "opaque") == 0) { mprFree(serverOpaque); serverOpaque = mprStrdup(value); } break; case 'q': if (mprStrCmpAnyCase(key, "qop") == 0) { mprFree(serverQop); serverQop = mprStrdup(value); } break; case 'r': if (mprStrCmpAnyCase(key, "realm") == 0) { mprFree(serverRealm); serverRealm = mprStrdup(value); } break; case 's': if (mprStrCmpAnyCase(key, "stale") == 0) { mprFree(serverStale); serverStale = mprStrdup(value); break; } default: // For upward compatibility -- ignore keywords we don't understand ; } key = tok; if (!seenComma) { while (*key && *key != ',') { key++; } if (*key) { key++; } } } if (strcmp(serverAuthType, "basic") == 0) { if (serverRealm == 0) { return MPR_ERR_BAD_ARGS; } else { return 0; } } if (serverRealm == 0 || serverNonce == 0) { return MPR_ERR_BAD_ARGS; } if (serverQop) { // FUTURE -- add checking for auth-int here if (serverDomain == 0 || serverOpaque == 0 || serverAlgorithm == 0 || serverStale == 0) { return MPR_ERR_BAD_ARGS; } } return 0; }