static void testCopyPath(MprTestGroup *gp) { MprFile *file; char *from, *to; from = sfmt("copyTest-%s.tmp", mprGetCurrentThreadName(gp)); assert(from != 0); file = mprOpenFile(from, O_CREAT | O_TRUNC | O_WRONLY, 0664); assert(file != 0); mprWriteFileString(file, "Hello World"); mprCloseFile(file); to = sfmt("newTest-%s.tmp", mprGetCurrentThreadName(gp)); assert(mprPathExists(from, F_OK)); mprCopyPath(from, to, 0664); assert(mprPathExists(to, F_OK)); mprDeletePath(from); mprDeletePath(to); }
static int doRequest(HttpConn *conn, cchar *url, MprList *files) { MprTicks mark, remaining; HttpLimits *limits; MprFile *outFile; cchar *path; assert(url && *url); limits = conn->limits; mprTrace(4, "fetch: %s %s", app->method, url); mark = mprGetTicks(); if (issueRequest(conn, url, files) < 0) { return MPR_ERR_CANT_CONNECT; } remaining = limits->requestTimeout; if (app->outFilename) { path = app->loadThreads > 1 ? sfmt("%s-%s.tmp", app->outFilename, mprGetCurrentThreadName()): app->outFilename; if ((outFile = mprOpenFile(path, O_CREAT | O_WRONLY | O_TRUNC | O_TEXT, 0664)) == 0) { mprError("Cannot open %s", path); return MPR_ERR_CANT_OPEN; } } else { outFile = mprGetStdout(); } mprAddRoot(outFile); while (!conn->tx->finalized && conn->state < HTTP_STATE_COMPLETE && remaining > 0) { remaining = mprGetRemainingTicks(mark, limits->requestTimeout); readBody(conn, outFile); httpWait(conn, 0, remaining); } if (conn->state < HTTP_STATE_COMPLETE && !conn->error) { httpError(conn, HTTP_ABORT | HTTP_CODE_REQUEST_TIMEOUT, "Inactive request timed out, exceeded request timeout %d", app->timeout); } else { readBody(conn, outFile); } if (app->outFilename) { mprCloseFile(outFile); } mprRemoveRoot(outFile); reportResponse(conn, url, mprGetTicks() - mark); httpDestroyRx(conn->rx); httpDestroyTx(conn->tx); return 0; }
static void trace(HttpConn *conn, cchar *url, int fetchCount, cchar *method, int status, MprOff contentLen) { if (sncasecmp(url, "http://", 7) != 0) { url += 7; } if ((fetchCount % 200) == 1) { if (fetchCount == 1 || (fetchCount % 5000) == 1) { if (fetchCount > 1) { mprPrintf("\n"); } mprPrintf(" Count Thread Op Code Bytes Url\n"); } mprPrintf("%7d %7s %4s %5d %7d %s\n", fetchCount - 1, mprGetCurrentThreadName(conn), method, status, (uchar) contentLen, url); } }
static void trace(MprHttp *http, cchar *url, int fetchCount, cchar *method, int code, int contentLen) { if (mprStrcmpAnyCaseCount(url, "http://", 7) != 0) { url += 7; } if ((fetchCount % 200) == 1) { if (fetchCount == 1 || (fetchCount % 5000) == 1) { if (fetchCount > 1) { mprPrintf(http, "\n"); } mprPrintf(http, " Count Thread Op Code Bytes Url\n"); } mprPrintf(http, "%7d %7s %4s %5d %7d %s\n", fetchCount - 1, mprGetCurrentThreadName(http), method, code, contentLen, url); } }
static int doRequest(HttpConn *conn, cchar *url, MprList *files) { MprFile *outFile; cchar *path; assert(url && *url); if (issueRequest(conn, url, files) < 0) { if (conn->rx && conn->rx->status) { reportResponse(conn, url); } return MPR_ERR_CANT_CONNECT; } if (app->outFilename) { path = app->loadThreads > 1 ? sfmt("%s-%s.tmp", app->outFilename, mprGetCurrentThreadName()): app->outFilename; if ((outFile = mprOpenFile(path, O_CREAT | O_WRONLY | O_TRUNC | O_TEXT, 0664)) == 0) { mprLog("error http", 0, "Cannot open %s", path); return MPR_ERR_CANT_OPEN; } } else { outFile = mprGetStdout(); } mprAddRoot(outFile); readBody(conn, outFile); while (conn->state < HTTP_STATE_COMPLETE && !httpRequestExpired(conn, -1)) { readBody(conn, outFile); httpWait(conn, 0, -1); } if (conn->state < HTTP_STATE_COMPLETE && !conn->error) { httpError(conn, HTTP_ABORT | HTTP_CODE_REQUEST_TIMEOUT, "Request timed out"); } if (app->outFilename) { mprCloseFile(outFile); } mprRemoveRoot(outFile); reportResponse(conn, url); httpDestroyRx(conn->rx); httpDestroyTx(conn->tx); return 0; }
/* Make a unique filename for a given thread */ static char *makePath(cchar *name) { return sfmt("%s-%d-%s", name, getpid(), mprGetCurrentThreadName()); }
/* Gather the child's exit status. WARNING: this may be called with a false-positive, ie. SIGCHLD will get invoked for all process deaths and not just when this cmd has completed. */ static void reapCmd(MprCmd *cmd, bool finalizing) { if (cmd->pid == 0) { return; } #if ME_UNIX_LIKE { int status, rc; status = 0; if ((rc = waitpid(cmd->pid, &status, WNOHANG | __WALL)) < 0) { mprLog("error mpr cmd", 0, "Waitpid failed for pid %d, errno %d", cmd->pid, errno); } else if (rc == cmd->pid) { if (!WIFSTOPPED(status)) { if (WIFEXITED(status)) { cmd->status = WEXITSTATUS(status); mprDebug("mpr cmd", 6, "Process exited pid %d, status %d", cmd->pid, cmd->status); } else if (WIFSIGNALED(status)) { cmd->status = WTERMSIG(status); } cmd->pid = 0; if (cmd->signal) { mprRemoveSignalHandler(cmd->signal); cmd->signal = 0; } } } else { mprDebug("mpr cmd", 6, "Still running pid %d, thread %s", cmd->pid, mprGetCurrentThreadName()); } } #endif #if VXWORKS /* The command exit status (cmd->status) is set in cmdTaskEntry */ if (!cmd->stopped) { if (semTake(cmd->exitCond, MPR_TIMEOUT_STOP_TASK) != OK) { mprLog("error mpr cmd", 0, "Child %s did not exit, errno %d", cmd->program, errno); return; } } semDelete(cmd->exitCond); cmd->exitCond = 0; cmd->pid = 0; #endif #if ME_WIN_LIKE { int status, rc; status = 0; if (GetExitCodeProcess(cmd->process, (ulong*) &status) == 0) { mprLog("error mpr cmd", 0, "GetExitProcess error"); return; } if (status != STILL_ACTIVE) { cmd->status = status; rc = CloseHandle(cmd->process); assert(rc != 0); rc = CloseHandle(cmd->thread); assert(rc != 0); cmd->process = 0; cmd->thread = 0; cmd->pid = 0; } } #endif if (cmd->pid == 0) { if (cmd->eofCount >= cmd->requiredEof) { completeCommand(cmd); } mprDebug("mpr cmd", 6, "Process reaped: status %d, pid %d, eof %d / %d", cmd->status, cmd->pid, cmd->eofCount, cmd->requiredEof); if (cmd->callback) { (cmd->callback)(cmd, -1, cmd->callbackData); } } }
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; }