static void myaction(HttpConn *conn) { HttpQueue *q; q = conn->writeq; /* Set the HTTP response status */ httpSetStatus(conn, 200); /* Add desired headers. "Set" will overwrite, add will create if not already defined. */ httpAddHeaderString(conn, "Content-Type", "text/plain"); httpSetHeaderString(conn, "Cache-Control", "no-cache"); httpWrite(q, "<html><title>simpleAction</title><body>\r\n"); httpWrite(q, "<p>Name: %s</p>\n", httpGetParam(conn, "name", "-")); httpWrite(q, "<p>Address: %s</p>\n", httpGetParam(conn, "address", "-")); httpWrite(q, "</body></html>\r\n"); /* Call finalize output and close the request. Delay closing if you want to do asynchronous output and close later. */ httpFinalize(conn); #if POSSIBLE /* Useful things to do in actions */ httpRedirect(conn, 302, "/other-uri"); httpError(conn, 409, "My message : %d", 5); #endif }
/* Start the request (and complete it) */ static void startDir(HttpQueue *q) { HttpConn *conn; HttpTx *tx; HttpRx *rx; MprList *list; MprDirEntry *dp; HttpDir *dir; cchar *path; uint nameSize; int next; conn = q->conn; rx = conn->rx; tx = conn->tx; if ((dir = conn->reqData) == 0) { httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "Cannot get directory listing"); return; } assert(tx->filename); if (!(rx->flags & (HTTP_GET | HTTP_HEAD))) { httpError(conn, HTTP_CODE_BAD_METHOD, "Bad method"); return; } httpSetContentType(conn, "text/html"); httpSetHeaderString(conn, "Cache-Control", "no-cache"); httpSetHeaderString(conn, "Last-Modified", conn->http->currentDate); parseQuery(conn); if ((list = mprGetPathFiles(tx->filename, MPR_PATH_RELATIVE)) == 0) { httpWrite(q, "<h2>Cannot get file list</h2>\r\n"); outputFooter(q); return; } if (dir->pattern) { filterDirList(conn, list); } sortList(conn, list); /* Get max filename size */ nameSize = 0; for (next = 0; (dp = mprGetNextItem(list, &next)) != 0; ) { nameSize = max((int) strlen(dp->name), nameSize); } nameSize = max(nameSize, 22); path = rx->route->prefix ? sjoin(rx->route->prefix, rx->pathInfo, NULL) : rx->pathInfo; outputHeader(q, path, nameSize); for (next = 0; (dp = mprGetNextItem(list, &next)) != 0; ) { outputLine(q, dp, tx->filename, nameSize); } outputFooter(q); httpFinalize(conn); }
static void outputFooter(HttpQueue *q) { HttpConn *conn; MprSocket *sock; Dir *dir; conn = q->conn; dir = conn->data; if (dir->fancyIndexing == 2) { httpWrite(q, "<tr><th colspan=\"5\"><hr /></th></tr>\r\n</table>\r\n"); } else if (dir->fancyIndexing == 1) { httpWrite(q, "<hr /></pre>\r\n"); } else { httpWrite(q, "</ul>\r\n"); } sock = conn->sock->listenSock; httpWrite(q, "<address>%s %s at %s Port %d</address>\r\n", BIT_TITLE, BIT_VERSION, sock->ip, sock->port); httpWrite(q, "</body></html>\r\n"); }
/* Write upload data. This routine blocks. If you need non-blocking ... cut and paste. */ ssize httpWriteUploadData(HttpConn *conn, MprList *fileData, MprList *formData) { char *path, *pair, *key, *value, *name; ssize rc; int next; rc = 0; if (formData) { for (rc = next = 0; rc >= 0 && (pair = mprGetNextItem(formData, &next)) != 0; ) { key = stok(sclone(pair), "=", &value); rc += httpWrite(conn->writeq, "%s\r\nContent-Disposition: form-data; name=\"%s\";\r\n", conn->boundary, key); rc += httpWrite(conn->writeq, "Content-Type: application/x-www-form-urlencoded\r\n\r\n%s\r\n", value); } } if (fileData) { for (rc = next = 0; rc >= 0 && (path = mprGetNextItem(fileData, &next)) != 0; ) { name = mprGetPathBase(path); rc += httpWrite(conn->writeq, "%s\r\nContent-Disposition: form-data; name=\"file%d\"; filename=\"%s\"\r\n", conn->boundary, next - 1, name); rc += httpWrite(conn->writeq, "Content-Type: %s\r\n\r\n", mprLookupMime(MPR->mimeTypes, path)); rc += blockingFileCopy(conn, path); rc += httpWrite(conn->writeq, "\r\n"); } } rc += httpWrite(conn->writeq, "%s--\r\n--", conn->boundary); httpFinalize(conn); return rc; }
static void processDir(HttpQueue *q) { HttpConn *conn; HttpTx *tx; HttpRx *rx; MprList *list; MprDirEntry *dp; Dir *dir; uint nameSize; int next; conn = q->conn; rx = conn->rx; tx = conn->tx; dir = conn->data; mprLog(5, "processDir"); mprAssert(tx->filename); httpSetHeaderString(conn, "Cache-Control", "no-cache"); httpSetHeaderString(conn, "Last-Modified", conn->http->currentDate); parseQuery(conn); list = mprGetPathFiles(tx->filename, 1); if (list == 0) { httpWrite(q, "<h2>Can't get file list</h2>\r\n"); outputFooter(q); return; } if (dir->pattern) { filterDirList(conn, list); } sortList(conn, list); /* Get max filename */ nameSize = 0; for (next = 0; (dp = mprGetNextItem(list, &next)) != 0; ) { nameSize = max((int) strlen(dp->name), nameSize); } nameSize = max(nameSize, 22); outputHeader(q, rx->pathInfo, nameSize); for (next = 0; (dp = mprGetNextItem(list, &next)) != 0; ) { outputLine(q, dp, tx->filename, nameSize); } outputFooter(q); httpFinalize(conn); }
/* self explanatory */ int soapPostSubmit(int fd, const char * url, const char * host, unsigned short port, const char * action, const char * body, const char * httpversion) { int bodysize; char headerbuf[512]; int headerssize; char portstr[8]; bodysize = (int)strlen(body); /* We are not using keep-alive HTTP connections. * HTTP/1.1 needs the header Connection: close to do that. * This is the default with HTTP/1.0 * Using HTTP/1.1 means we need to support chunked transfer-encoding : * When using HTTP/1.1, the router "BiPAC 7404VNOX" always use chunked * transfer encoding. */ /* Connection: Close is normally there only in HTTP/1.1 but who knows */ portstr[0] = '\0'; if(port != 80) snprintf(portstr, sizeof(portstr), ":%hu", port); headerssize = snprintf(headerbuf, sizeof(headerbuf), "POST %s HTTP/%s\r\n" "Host: %s%s\r\n" "User-Agent: " OS_STRING ", " UPNP_VERSION_STRING ", MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n" "Content-Length: %d\r\n" "Content-Type: text/xml\r\n" "SOAPAction: \"%s\"\r\n" "Connection: Close\r\n" "Cache-Control: no-cache\r\n" /* ??? */ "Pragma: no-cache\r\n" "\r\n", url, httpversion, host, portstr, bodysize, action); if ((unsigned int)headerssize >= sizeof(headerbuf)) return -1; #ifdef DEBUG /*printf("SOAP request : headersize=%d bodysize=%d\n", headerssize, bodysize); */ printf("SOAP request : POST %s HTTP/%s - Host: %s%s\n", url, httpversion, host, portstr); printf("SOAPAction: \"%s\" - Content-Length: %d\n", action, bodysize); printf("Headers :\n%s", headerbuf); printf("Body :\n%s\n", body); #endif return httpWrite(fd, body, bodysize, headerbuf, headerssize); }
bool simpleForm(MprTestGroup *gp, char *uri, char *formData, int expectStatus) { HttpConn *conn; MprOff contentLen; ssize len; int status; contentLen = 0; if (expectStatus <= 0) { expectStatus = 200; } if (startRequest(gp, "POST", uri) < 0) { return 0; } conn = getConn(gp); if (formData) { httpSetHeader(conn, "Content-Type", "application/x-www-form-urlencoded"); len = slen(formData); if (httpWrite(conn->writeq, formData, len) != len) { return MPR_ERR_CANT_WRITE; } } httpFinalizeOutput(conn); if (httpWait(conn, HTTP_STATE_COMPLETE, -1) < 0) { return MPR_ERR_CANT_READ; } status = httpGetStatus(conn); if (status != expectStatus) { mprLog("appweb test form", 0, "Client failed for %s, response code: %d, msg %s", uri, status, httpGetStatusMessage(conn)); return 0; } gp->content = httpReadString(conn); contentLen = httpGetContentLength(conn); if (! tassert(gp->content != 0 && contentLen > 0)) { return 0; } return 1; }
/* relativement clair */ int soapPostSubmit(int fd, const char * url, const char * host, unsigned short port, const char * action, const char * body) { int bodysize; char headerbuf[1024]; bodysize = strlen(body); snprintf(headerbuf, 1024, "POST %s HTTP/1.1\r\n" "HOST: %s:%d\r\n" "Content-length: %d\r\n" "Content-Type: text/xml\r\n" "SOAPAction: \"%s\"\r\n" "\r\n", url, host, port, bodysize, action); //puts(headerbuf); //fwrite(body, 1, bodysize, stdout); return httpWrite(fd, body, bodysize, headerbuf); }
bool simplePost(MprTestGroup *gp, char *uri, char *bodyData, ssize len, int expectStatus) { HttpConn *conn; MprOff contentLen; int status; contentLen = 0; conn = getConn(gp); if (expectStatus <= 0) { expectStatus = 200; } if (startRequest(gp, "POST", uri) < 0) { return 0; } if (bodyData) { if (httpWrite(conn->writeq, bodyData, len) != len) { return MPR_ERR_CANT_WRITE; } } httpFinalizeOutput(conn); if (httpWait(conn, HTTP_STATE_COMPLETE, -1) < 0) { return MPR_ERR_CANT_READ; } status = httpGetStatus(conn); if (status != expectStatus) { mprLog("appweb test post", 0, "Client failed for %s, response code: %d, msg %s", uri, status, httpGetStatusMessage(conn)); return 0; } gp->content = httpReadString(conn); contentLen = httpGetContentLength(conn); if (! tassert(gp->content != 0 && contentLen > 0)) { return 0; } return 1; }
/* Run the handler. This is called when all input data has been received. */ static void processSimple(HttpQueue *q) { HttpConn *conn; conn = q->conn; httpSetHeader(conn, 0, "Last-Modified", conn->http->currentDate); /* Create the empty header packet. This will be filled in by the downstream network connector stage. */ httpPutForService(q, httpCreateHeaderPacket(conn), 0); /* Generate some dynamic data. If you generate a lot, this will buffer up to a configured maximum. If that limit is exceeded, the packet will be sent downstream and the response headers will be created. */ httpWrite(q, "Hello World"); /* Send an end of data packet */ httpPutForService(q, httpCreateEndPacket(conn), 1); }
/* Write upload data. This routine blocks. If you need non-blocking ... cut and paste. */ PUBLIC ssize httpWriteUploadData(HttpConn *conn, MprList *fileData, MprList *formData) { char *path, *pair, *key, *value, *name; cchar *type; ssize rc; int next; rc = 0; if (formData) { for (rc = next = 0; rc >= 0 && (pair = mprGetNextItem(formData, &next)) != 0; ) { key = ssplit(sclone(pair), "=", &value); rc += httpWrite(conn->writeq, "%s\r\nContent-Disposition: form-data; name=\"%s\";\r\n", conn->boundary, key); rc += httpWrite(conn->writeq, "Content-Type: application/x-www-form-urlencoded\r\n\r\n%s\r\n", value); } } if (fileData) { for (rc = next = 0; rc >= 0 && (path = mprGetNextItem(fileData, &next)) != 0; ) { if (!mprPathExists(path, R_OK)) { httpError(conn, HTTP_CODE_NOT_FOUND, "Cannot open %s", path); return MPR_ERR_CANT_OPEN; } name = mprGetPathBase(path); rc += httpWrite(conn->writeq, "%s\r\nContent-Disposition: form-data; name=\"file%d\"; filename=\"%s\"\r\n", conn->boundary, next - 1, name); if ((type = mprLookupMime(MPR->mimeTypes, path)) != 0) { rc += httpWrite(conn->writeq, "Content-Type: %s\r\n", mprLookupMime(MPR->mimeTypes, path)); } httpWrite(conn->writeq, "\r\n"); if (blockingFileCopy(conn, path) < 0) { return MPR_ERR_CANT_WRITE; } rc += httpWrite(conn->writeq, "\r\n"); } } rc += httpWrite(conn->writeq, "%s--\r\n--", conn->boundary); return rc; }
static ssize writeBody(HttpConn *conn, MprList *files) { MprFile *file; char buf[ME_MAX_BUFFER], *path, *pair; ssize bytes, len, count, nbytes, sofar; int next; if (app->upload) { if (httpWriteUploadData(conn, app->files, app->formData) < 0) { return MPR_ERR_CANT_WRITE; } } else { if (app->formData) { count = mprGetListLength(app->formData); for (next = 0; (pair = mprGetNextItem(app->formData, &next)) != 0; ) { len = strlen(pair); if (next < count) { len = slen(pair); if (httpWriteString(conn->writeq, pair) != len || httpWriteString(conn->writeq, "&") != 1) { return MPR_ERR_CANT_WRITE; } } else { if (httpWrite(conn->writeq, pair, len) != len) { return MPR_ERR_CANT_WRITE; } } } } if (files) { assert(mprGetListLength(files) == 1); for (next = 0; (path = mprGetNextItem(files, &next)) != 0; ) { if (strcmp(path, "-") == 0) { file = mprAttachFileFd(0, "stdin", O_RDONLY | O_BINARY); } else { file = mprOpenFile(path, O_RDONLY | O_BINARY, 0); } if (file == 0) { mprLog("error http", 0, "Cannot open \"%s\"", path); return MPR_ERR_CANT_OPEN; } app->inFile = file; if (app->verbose) { mprPrintf("uploading: %s\n", path); } while ((bytes = mprReadFile(file, buf, sizeof(buf))) > 0) { sofar = 0; while (bytes > 0) { if ((nbytes = httpWriteBlock(conn->writeq, &buf[sofar], bytes, HTTP_BLOCK)) < 0) { mprCloseFile(file); return MPR_ERR_CANT_WRITE; } bytes -= nbytes; sofar += nbytes; assert(bytes >= 0); } } httpFlushQueue(conn->writeq, HTTP_BLOCK); mprCloseFile(file); app->inFile = 0; } } if (app->bodyData) { len = mprGetBufLength(app->bodyData); if (httpWriteBlock(conn->writeq, mprGetBufStart(app->bodyData), len, HTTP_BLOCK) != len) { return MPR_ERR_CANT_WRITE; } } } return 0; }
/* httpWrite sends the headers and the body to the socket * and returns the number of bytes sent */ static int httpWrite(int fd, const char * body, int bodysize, const char * headers, int headerssize) { int n = 0; /*n = write(fd, headers, headerssize);*/ /*if(bodysize>0) n += write(fd, body, bodysize);*/ /* Note : my old linksys router only took into account * soap request that are sent into only one packet */ char * p; /* TODO: AVOID MALLOC */ p = malloc(headerssize+bodysize); if(!p) return 0; memcpy(p, headers, headerssize); memcpy(p+headerssize, body, bodysize); /*n = write(fd, p, headerssize+bodysize);*/ n = send(fd, p, headerssize+bodysize, 0); if(n<0) { PRINT_SOCKET_ERROR("send"); } /* disable send on the socket */ /* draytek routers dont seems to like that... */ #if 0 #ifdef _WIN32 if(shutdown(fd, SD_SEND)<0) { #else if(shutdown(fd, SHUT_WR)<0) { /*SD_SEND*/ #endif PRINT_SOCKET_ERROR("shutdown"); } #endif free(p); return n; } /* self explanatory */ int soapPostSubmit(int fd, const char * url, const char * host, unsigned short port, const char * action, const char * body, const char * httpversion) { int bodysize; char headerbuf[512]; int headerssize; char portstr[8]; bodysize = (int)strlen(body); /* We are not using keep-alive HTTP connections. * HTTP/1.1 needs the header Connection: close to do that. * This is the default with HTTP/1.0 * Using HTTP/1.1 means we need to support chunked transfer-encoding : * When using HTTP/1.1, the router "BiPAC 7404VNOX" always use chunked * transfer encoding. */ /* Connection: Close is normally there only in HTTP/1.1 but who knows */ portstr[0] = '\0'; if(port != 80) snprintf(portstr, sizeof(portstr), ":%hu", port); headerssize = snprintf(headerbuf, sizeof(headerbuf), "POST %s HTTP/%s\r\n" "Host: %s%s\r\n" "User-Agent: " OS_STRING ", UPnP/1.0, MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n" "Content-Length: %d\r\n" "Content-Type: text/xml\r\n" "SOAPAction: \"%s\"\r\n" "Connection: Close\r\n" "Cache-Control: no-cache\r\n" /* ??? */ "Pragma: no-cache\r\n" "\r\n", url, httpversion, host, portstr, bodysize, action); #ifdef DEBUG /*printf("SOAP request : headersize=%d bodysize=%d\n", headerssize, bodysize); */ printf("SOAP request : POST %s HTTP/%s - Host: %s%s\n", url, httpversion, host, portstr); printf("SOAPAction: \"%s\" - Content-Length: %d\n", action, bodysize); printf("Headers :\n%s", headerbuf); printf("Body :\n%s\n", body); #endif return httpWrite(fd, body, bodysize, headerbuf, headerssize); }
static void outputLine(HttpQueue *q, MprDirEntry *ep, cchar *path, int nameSize) { MprPath info; MprTime when; Dir *dir; char *newPath, sizeBuf[16], timeBuf[48], *icon; struct tm tm; bool isDir; int len; cchar *ext, *mimeType; char *dirSuffix; char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; path = mprEscapeHtml(path); dir = q->conn->data; if (ep->size >= (1024 * 1024 * 1024)) { fmtNum(sizeBuf, sizeof(sizeBuf), (int) ep->size, 1024 * 1024 * 1024, "G"); } else if (ep->size >= (1024 * 1024)) { fmtNum(sizeBuf, sizeof(sizeBuf), (int) ep->size, 1024 * 1024, "M"); } else if (ep->size >= 1024) { fmtNum(sizeBuf, sizeof(sizeBuf), (int) ep->size, 1024, "K"); } else { fmt(sizeBuf, sizeof(sizeBuf), "%6d", (int) ep->size); } newPath = mprJoinPath(path, ep->name); if (mprGetPathInfo(newPath, &info) < 0) { when = mprGetTime(); isDir = 0; } else { isDir = info.isDir ? 1 : 0; when = (MprTime) info.mtime * MPR_TICKS_PER_SEC; } if (isDir) { icon = "folder"; dirSuffix = "/"; } else { ext = mprGetPathExt(ep->name); if (ext && (mimeType = mprLookupMime(q->conn->rx->route->mimeTypes, ext)) != 0) { if (strcmp(ext, "es") == 0 || strcmp(ext, "ejs") == 0 || strcmp(ext, "php") == 0) { icon = "text"; } else if (strstr(mimeType, "text") != 0) { icon = "text"; } else { icon = "compressed"; } } else { icon = "compressed"; } dirSuffix = ""; } mprDecodeLocalTime(&tm, when); fmt(timeBuf, sizeof(timeBuf), "%02d-%3s-%4d %02d:%02d", tm.tm_mday, months[tm.tm_mon], tm.tm_year + 1900, tm.tm_hour, tm.tm_min); len = (int) strlen(ep->name) + (int) strlen(dirSuffix); if (dir->fancyIndexing == 2) { httpWrite(q, "<tr><td valign=\"top\">"); httpWrite(q, "<img src=\"/icons/%s.gif\" alt=\"[ ]\", /></td>", icon); httpWrite(q, "<td><a href=\"%s%s\">%s%s</a></td>", ep->name, dirSuffix, ep->name, dirSuffix); httpWrite(q, "<td>%s</td><td>%s</td></tr>\r\n", timeBuf, sizeBuf); } else if (dir->fancyIndexing == 1) { httpWrite(q, "<img src=\"/icons/%s.gif\" alt=\"[ ]\", /> ", icon); httpWrite(q, "<a href=\"%s%s\">%s%s</a>%-*s %17s %4s\r\n", ep->name, dirSuffix, ep->name, dirSuffix, nameSize - len, "", timeBuf, sizeBuf); } else { httpWrite(q, "<li><a href=\"%s%s\"> %s%s</a></li>\r\n", ep->name, dirSuffix, ep->name, dirSuffix); } }
void translate_messages(const char *language)/* I - Output language... */ { /* * Google provides a simple translation/language tool for translating * from one language to another. It is far from perfect, however it * can be used to get a basic translation done or update an existing * translation when no other resources are available. * * Translation requests are sent as HTTP POSTs to * "http://translate.google.com/translate_t" with the following form * variables: * * Name Description Value * -------- ---------------------------------- ---------------- * hl Help language? "en" * ie Input encoding "UTF8" * langpair Language pair "en|" + language * oe Output encoding "UTF8" * text Text to translate translation string */ int i; /* Looping var */ message_t *m; /* Current message */ int tries; /* Number of tries... */ http_t *http; /* HTTP connection */ http_status_t status; /* Status of POST request */ char *idptr, /* Pointer into msgid */ *strptr, /* Pointer into msgstr */ buffer[65536], /* Input/output buffer */ *bufptr, /* Pointer into buffer */ *bufend, /* Pointer to end of buffer */ length[16]; /* Content length */ unsigned char *utf8; /* UTF-8 string */ int ch; /* Current decoded character */ int bytes; /* Number of bytes read */ /* * Connect to translate.google.com... */ puts("Connecting to translate.google.com..."); if ((http = httpConnect("translate.google.com", 80)) == NULL) { perror("Unable to connect to translate.google.com"); return; } /* * Scan the current messages, requesting a translation of any untranslated * messages... */ for (i = num_messages, m = messages; i > 0; i --, m ++) { /* * Skip messages that are already translated... */ if (m->str && m->str[0]) continue; /* * Encode the form data into the buffer... */ snprintf(buffer, sizeof(buffer), "hl=en&ie=UTF8&langpair=en|%s&oe=UTF8&text=", language); bufptr = buffer + strlen(buffer); bufend = buffer + sizeof(buffer) - 5; for (idptr = m->id; *idptr && bufptr < bufend; idptr ++) if (*idptr == ' ') *bufptr++ = '+'; else if (*idptr < ' ' || *idptr == '%') { sprintf(bufptr, "%%%02X", *idptr & 255); bufptr += 3; } else if (*idptr != '&') *bufptr++ = *idptr; *bufptr++ = '&'; *bufptr = '\0'; sprintf(length, "%d", bufptr - buffer); /* * Send the request... */ printf("\"%s\" = ", m->id); fflush(stdout); tries = 0; do { httpClearFields(http); httpSetField(http, HTTP_FIELD_CONTENT_TYPE, "application/x-www-form-urlencoded"); httpSetField(http, HTTP_FIELD_CONTENT_LENGTH, length); if (httpPost(http, "/translate_t")) { httpReconnect(http); httpPost(http, "/translate_t"); } httpWrite(http, buffer, bufptr - buffer); while ((status = httpUpdate(http)) == HTTP_CONTINUE); if (status != HTTP_OK && status != HTTP_ERROR) httpFlush(http); tries ++; } while (status == HTTP_ERROR && tries < 10); if (status == HTTP_OK) { /* * OK, read the translation back... */ bufptr = buffer; bufend = buffer + sizeof(buffer) - 1; while ((bytes = httpRead(http, bufptr, bufend - bufptr)) > 0) bufptr += bytes; if (bytes < 0) { /* * Read error, abort! */ puts("READ ERROR!"); break; } *bufptr = '\0'; /* * Find the first textarea element - that will have the translation data... */ if ((bufptr = strstr(buffer, "<textarea")) == NULL) { /* * No textarea, abort! */ puts("NO TEXTAREA!"); break; } if ((bufptr = strchr(bufptr, '>')) == NULL) { /* * textarea doesn't end, abort! */ puts("TEXTAREA SHORT DATA!"); break; } utf8 = (unsigned char *)bufptr + 1; if ((bufend = strstr(bufptr, "</textarea>")) == NULL) { /* * textarea doesn't close, abort! */ puts("/TEXTAREA SHORT DATA!"); break; } *bufend = '\0'; /* * Copy the UTF-8 translation to ISO-8859-1 (for now)... */ m->str = malloc(bufend - bufptr); for (strptr = m->str; *utf8;) if (*utf8 < 0x80) *strptr++ = *utf8++; else { if ((*utf8 & 0xe0) == 0xc0) { /* * Two-byte encoding... */ ch = ((utf8[0] & 0x1f) << 6) | (utf8[1] & 0x3f); utf8 += 2; } else if ((ch & 0xf0) == 0xe0) { /* * Three-byte encoding... */ ch = ((((utf8[0] & 0x0f) << 6) | (utf8[1] & 0x3f)) << 6) | (utf8[2] & 0x3f); utf8 += 3; } if (ch < 256) /* ISO-8859-1 */ *strptr++ = ch; else if (ch == 0x20ac) /* Euro */ *strptr++ = 0xA4; /* ISO-8859-15 mapping */ } *strptr = '\0'; printf("\"%s\"\n", m->str); } else if (status == HTTP_ERROR) { printf("NETWORK ERROR (%s)!\n", strerror(httpError(http))); break; } else { printf("HTTP ERROR %d!\n", status); break; } } httpClose(http); }
static void outputHeader(HttpQueue *q, cchar *path, int nameSize) { Dir *dir; char *parent, *parentSuffix; int reverseOrder, fancy, isRootDir; dir = q->conn->data; fancy = 1; path = mprEscapeHtml(path); httpWrite(q, "<!DOCTYPE HTML PUBLIC \"-/*W3C//DTD HTML 3.2 Final//EN\">\r\n"); httpWrite(q, "<html>\r\n <head>\r\n <title>Index of %s</title>\r\n", path); httpWrite(q, " </head>\r\n"); httpWrite(q, "<body>\r\n"); httpWrite(q, "<h1>Index of %s</h1>\r\n", path); if (dir->sortOrder > 0) { reverseOrder = 'D'; } else { reverseOrder = 'A'; } if (dir->fancyIndexing == 0) { fancy = '0'; } else if (dir->fancyIndexing == 1) { fancy = '1'; } else if (dir->fancyIndexing == 2) { fancy = '2'; } parent = mprGetPathDir(path); if (parent[strlen(parent) - 1] != '/') { parentSuffix = "/"; } else { parentSuffix = ""; } isRootDir = (strcmp(path, "/") == 0); if (dir->fancyIndexing == 2) { httpWrite(q, "<table><tr><th><img src=\"/icons/blank.gif\" alt=\"[ICO]\" /></th>"); httpWrite(q, "<th><a href=\"?C=N;O=%c;F=%c\">Name</a></th>", reverseOrder, fancy); httpWrite(q, "<th><a href=\"?C=M;O=%c;F=%c\">Last modified</a></th>", reverseOrder, fancy); httpWrite(q, "<th><a href=\"?C=S;O=%c;F=%c\">Size</a></th>", reverseOrder, fancy); httpWrite(q, "<th><a href=\"?C=D;O=%c;F=%c\">Description</a></th>\r\n", reverseOrder, fancy); httpWrite(q, "</tr><tr><th colspan=\"5\"><hr /></th></tr>\r\n"); if (! isRootDir) { httpWrite(q, "<tr><td valign=\"top\"><img src=\"/icons/back.gif\""); httpWrite(q, "alt=\"[DIR]\" /></td><td><a href=\"%s%s\">", parent, parentSuffix); httpWrite(q, "Parent Directory</a></td>"); httpWrite(q, "<td align=\"right\"> - </td></tr>\r\n"); } } else if (dir->fancyIndexing == 1) { httpWrite(q, "<pre><img src=\"/icons/space.gif\" alt=\"Icon\" /> "); httpWrite(q, "<a href=\"?C=N;O=%c;F=%c\">Name</a>%*s", reverseOrder, fancy, nameSize - 3, " "); httpWrite(q, "<a href=\"?C=M;O=%c;F=%c\">Last modified</a> ", reverseOrder, fancy); httpWrite(q, "<a href=\"?C=S;O=%c;F=%c\">Size</a> ", reverseOrder, fancy); httpWrite(q, "<a href=\"?C=D;O=%c;F=%c\">Description</a>\r\n", reverseOrder, fancy); httpWrite(q, "<hr />"); if (! isRootDir) { httpWrite(q, "<img src=\"/icons/parent.gif\" alt=\"[DIR]\" />"); httpWrite(q, " <a href=\"%s%s\">Parent Directory</a>\r\n", parent, parentSuffix); } } else { httpWrite(q, "<ul>\n"); if (! isRootDir) { httpWrite(q, "<li><a href=\"%s%s\"> Parent Directory</a></li>\r\n", parent, parentSuffix); } } }
static void processProxy(HttpQueue *q) { int count = 50000; q->max = 65536; #if USE0 /* May overflow q->max */ while (sofar < count) { httpWrite(q, "%d aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n", sofar++); } httpFinalizeOutput(q->conn); sofar = 0; #endif #if USE1 httpWrite(q, "%d aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n", sofar++); if (sofar == count) { httpFinalizeOutput(q->conn); sofar = 0; } #endif #if USE2 while (sofar < count && q->count < (q->max * 3 / 4)) { /* NOTE: httpWrite may do internal flush if count > max */ httpWrite(q, "%d aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n", sofar++); } if (sofar == count) { httpFinalizeOutput(q->conn); sofar = 0; } #endif #if USE3 /* MANUAL FLOW CONTROL */ HttpPacket *packet; int i, size; size = 1024; for (; sofar < count && q->count < q->max; sofar++) { packet = httpCreateDataPacket(size); for (i = 1; i < size - 1; i++) { mprPutCharToBuf(packet->content, 'a'); } mprPutCharToBuf(packet->content, '\n'); httpPutForService(q, packet, HTTP_DELAY_SERVICE); } if (sofar == count) { httpFinalizeOutput(q->conn); sofar = 0; } #endif #if USE4 || 1 httpStealConn(q->conn); #endif }
static void _post_write_data (GtkCupsRequest *request) { gsize bytes; char buffer[_GTK_CUPS_MAX_CHUNK_SIZE]; http_status_t http_status; GTK_NOTE (PRINTING, g_print ("CUPS Backend: %s\n", G_STRFUNC)); request->poll_state = GTK_CUPS_HTTP_WRITE; if (httpCheck (request->http)) http_status = httpUpdate (request->http); else http_status = request->last_status; request->last_status = http_status; if (http_status == HTTP_CONTINUE || http_status == HTTP_OK) { GIOStatus io_status; GError *error; error = NULL; /* send data */ io_status = g_io_channel_read_chars (request->data_io, buffer, _GTK_CUPS_MAX_CHUNK_SIZE, &bytes, &error); if (io_status == G_IO_STATUS_ERROR) { request->state = GTK_CUPS_POST_DONE; request->poll_state = GTK_CUPS_HTTP_IDLE; gtk_cups_result_set_error (request->result, GTK_CUPS_ERROR_IO, io_status, error->code, "Error reading from cache file: %s", error->message); g_error_free (error); return; } else if (bytes == 0 && io_status == G_IO_STATUS_EOF) { request->state = GTK_CUPS_POST_CHECK; request->poll_state = GTK_CUPS_HTTP_READ; request->attempts = 0; return; } #if HAVE_CUPS_API_1_2 if (httpWrite2 (request->http, buffer, bytes) < bytes) #else if (httpWrite (request->http, buffer, (int) bytes) < bytes) #endif /* HAVE_CUPS_API_1_2 */ { int http_errno; http_errno = httpError (request->http); request->state = GTK_CUPS_POST_DONE; request->poll_state = GTK_CUPS_HTTP_IDLE; gtk_cups_result_set_error (request->result, GTK_CUPS_ERROR_HTTP, http_status, http_errno, "Error writing to socket in Post %s", g_strerror (http_errno)); return; } } else if (http_status == HTTP_UNAUTHORIZED) { request->state = GTK_CUPS_POST_CHECK; request->poll_state = GTK_CUPS_HTTP_READ; request->attempts = 0; return; } else { request->attempts++; } }
/** * Finalize the configuration page and output it to the HTTP device. * @param devptr pointer to the current device for httpWrite calls */ int outputConfig(device *devptr, int flashSuccess) { device *ethptr; struct http *webptr; int cntr; /* Format strings for output to underlying device */ char *oneforall, *oneper, *formsubmit, *flashReport; flashReport = NULL; /* Pointers for nvramGet() return values */ char *configDomainname, *configGatewayIP; char *configHostname, *configIP, *configSubnetMask; /* Size variables for NVRAM configuration options */ int hostname_strsz, domainname_strsz, lan_ip_strsz; int subnet_mask_strsz, gate_ip_strsz; /* Lengths of NVRAM lookup strings + null termination character */ hostname_strsz = strnlen(NET_HOSTNAME, NVRAM_STRMAX) + 1; domainname_strsz = strnlen(NET_DOMAINNAME, NVRAM_STRMAX) + 1; lan_ip_strsz = strnlen(NET_LAN_IPADDR, NVRAM_STRMAX) + 1; subnet_mask_strsz = strnlen(NET_SUBNET_MASK, NVRAM_STRMAX) + 1; gate_ip_strsz = strnlen(NET_GATEWAY, NVRAM_STRMAX) + 1; /* Setup device pointer */ webptr = &httptab[devptr->minor]; /* Setup local pointers to device character pointers */ char *hostname_str = webptr->hostname_str; char *domainname_str = webptr->domainname_str; char *lan_ip_str = webptr->lan_ip_str; char *subnet_mask_str = webptr->subnet_mask_str; char *gate_ip_str = webptr->gate_ip_str; /* Zero out the nvram string lookup buffers */ bzero(hostname_str, hostname_strsz + DEVMAXNAME); bzero(domainname_str, domainname_strsz + DEVMAXNAME); bzero(lan_ip_str, lan_ip_strsz + DEVMAXNAME); bzero(subnet_mask_str, subnet_mask_strsz + DEVMAXNAME); bzero(gate_ip_str, gate_ip_strsz + DEVMAXNAME); /* Configuration settings, 1 for all devices */ oneforall = "<form method='POST' name='configform'" " action='config.html' target='_self'>" "<table align=center>" "<tr>" "<td>Gateway IP Address:</td>" "<td>" "<input type='text' name='%s'" " value='%s' maxlength='%d' width='32' />" "</td>" "</tr>" "<tr>" "<td colspan='2'><hr></td>" "</tr>"; /* Configuration settings, 1 per device */ oneper = "<tr>" "<td colspan='2' align='left'>%s:</td>" "</tr>" "<tr>" "<td>Host Name:</td>" "<td>" "<input type='text' name='%s'" " value='%s' maxlength='%d' width='32' />" "</td>" "<tr>" "<tr>" "<td>Domain Name:</td>" "<td>" "<input type='text' name='%s'" " value='%s' maxlength='%d' width='32' />" "</td>" "<tr>" "<td>Local IP Address:</td>" "<td>" "<input type='text' name='%s'" " value='%s' maxlength='%d' width='32' />" "</td>" "</tr>" "<td>Subnet Mask:</td>" "<td>" "<input type='text' name='%s'" " value='%s' maxlength='%d' width='32' />" "</td>" "</tr>" "<tr>" "<td colspan='2'><hr></td>" "</tr>"; formsubmit = "<tr>" "<td align='center' colspan='2'>" "<input type='submit' value='Submit Changes' />" "</td>" "</table>" "</form>"; /* Report on the success of updating router configuration in NVRAM */ switch (flashSuccess) { case 0: flashReport = "<div style='color:#00ff00' align='center'>" "Updated router configuration settings, restart required." "</div>"; break; case 1: flashReport = "<div style='color:#ff0000' align='center'>" "Failed to update router configuration settings." "</div>"; break; default: flashReport = NULL; } if (NULL != flashReport) { httpWrite(devptr, flashReport, strnlen(flashReport, HTTP_STR_SM)); } /* Settings that pertain to all devices */ if (NULL == (configGatewayIP = nvramGet(NET_GATEWAY))) { configGatewayIP = "not set"; } printf(oneforall, NET_GATEWAY, configGatewayIP, IPv4_DOTDEC_MAXLEN); /* Settings that are per device */ for (cntr = 0; cntr < NETHER; cntr++) { ethptr = ethertab[cntr].dev; if (NULL == ethptr) { continue; } sprintf(hostname_str, "%s_%s", ethptr->name, NET_HOSTNAME); sprintf(domainname_str, "%s_%s", ethptr->name, NET_DOMAINNAME); sprintf(lan_ip_str, "%s_%s", ethptr->name, NET_LAN_IPADDR); sprintf(subnet_mask_str, "%s_%s", ethptr->name, NET_SUBNET_MASK); if (NULL == (configHostname = nvramGet(hostname_str))) { configHostname = "not set"; } if (NULL == (configDomainname = nvramGet(domainname_str))) { configDomainname = "not set"; } if (NULL == (configIP = nvramGet(lan_ip_str))) { configIP = "not set"; } if (NULL == (configSubnetMask = nvramGet(subnet_mask_str))) { configSubnetMask = "not set"; } printf(oneper, /* Format string for settings per device */ ethptr->name, /* Device name */ hostname_str, configHostname, NET_HOSTNM_MAXLEN, domainname_str, configDomainname, NVRAM_STRMAX, lan_ip_str, configIP, IPv4_DOTDEC_MAXLEN, subnet_mask_str, configSubnetMask, IPv4_DOTDEC_MAXLEN); } /* Output the bottom of the configuration page body */ httpWrite(devptr, formsubmit, strnlen(formsubmit, HTTP_STR_MD)); /* Free memory of configuration page strings */ if (hostname_str != NULL) { free(hostname_str); } if (domainname_str != NULL) { free(domainname_str); } if (lan_ip_str != NULL) { free(lan_ip_str); } if (subnet_mask_str != NULL) { free(subnet_mask_str); } if (gate_ip_str != NULL) { free(gate_ip_str); } return OK; }
static ssize writeBody(HttpConn *conn, MprList *files) { MprFile *file; char buf[HTTP_BUFSIZE], *path, *pair; ssize bytes, len, count, nbytes, sofar; int next, oldMode; if (app->upload) { if (httpWriteUploadData(conn, app->files, app->formData) < 0) { mprError("Can't write upload data %s", httpGetError(conn)); return MPR_ERR_CANT_WRITE; } } else { if (app->formData) { count = mprGetListLength(app->formData); for (next = 0; (pair = mprGetNextItem(app->formData, &next)) != 0; ) { len = strlen(pair); if (next < count) { len = slen(pair); if (httpWrite(conn->writeq, pair, len) != len || httpWrite(conn->writeq, "&", 1) != 1) { return MPR_ERR_CANT_WRITE; } } else { if (httpWrite(conn->writeq, pair, len) != len) { return MPR_ERR_CANT_WRITE; } } } } if (files) { mprAssert(mprGetListLength(files) == 1); for (next = 0; (path = mprGetNextItem(files, &next)) != 0; ) { if (strcmp(path, "-") == 0) { file = mprAttachFileFd(0, "stdin", O_RDONLY | O_BINARY); } else { file = mprOpenFile(path, O_RDONLY | O_BINARY, 0); } if (file == 0) { mprError("Can't open \"%s\"", path); return MPR_ERR_CANT_OPEN; } app->inFile = file; if (app->verbose) { mprPrintf("uploading: %s\n", path); } oldMode = mprSetSocketBlockingMode(conn->sock, 1); while ((bytes = mprReadFile(file, buf, sizeof(buf))) > 0) { sofar = 0; while (bytes > 0) { if ((nbytes = httpWriteBlock(conn->writeq, &buf[sofar], bytes)) < 0) { mprCloseFile(file); return MPR_ERR_CANT_WRITE; } bytes -= nbytes; sofar += nbytes; mprAssert(bytes >= 0); } mprYield(0); } httpFlushQueue(conn->writeq, 1); mprSetSocketBlockingMode(conn->sock, oldMode); mprCloseFile(file); app->inFile = 0; } } if (app->bodyData) { mprAddNullToBuf(app->bodyData); len = mprGetBufLength(app->bodyData); if (httpWriteBlock(conn->writeq, mprGetBufStart(app->bodyData), len) != len) { return MPR_ERR_CANT_WRITE; } } } return 0; }