PUBLIC int websProcessCgiData(Webs *wp) { ssize nbytes; nbytes = bufLen(&wp->input); trace(5, "cgi: write %d bytes to CGI program", nbytes); if (write(wp->cgifd, wp->input.servp, (int) nbytes) != nbytes) { websError(wp, HTTP_CODE_INTERNAL_SERVER_ERROR| WEBS_CLOSE, "Can't write to CGI gateway"); return -1; } websConsumeInput(wp, nbytes); trace(5, "cgi: write %d bytes to CGI program", nbytes); return 0; }
PUBLIC int websProcessPutData(Webs *wp) { ssize nbytes; assert(wp); assert(wp->putfd >= 0); assert(wp->input.buf); nbytes = bufLen(&wp->input); wp->putLen += nbytes; if (wp->putLen > ME_GOAHEAD_LIMIT_PUT) { websError(wp, HTTP_CODE_REQUEST_TOO_LARGE | WEBS_CLOSE, "Put file too large"); return -1; } if (write(wp->putfd, wp->input.servp, (int) nbytes) != nbytes) { websError(wp, HTTP_CODE_INTERNAL_SERVER_ERROR | WEBS_CLOSE, "Cannot write to file"); return -1; } websConsumeInput(wp, nbytes); return 0; }
static int processContentData(Webs *wp) { WebsUpload *file; WebsBuf *content; ssize size, nbytes; char *data, *bp; content = &wp->input; file = wp->currentFile; size = bufLen(content); if (size < wp->boundaryLen) { /* Incomplete boundary. Return and get more data */ return 0; } if ((bp = getBoundary(wp, content->servp, size)) == 0) { trace(7, "uploadFilter: Got boundary filename %x", wp->clientFilename); if (wp->clientFilename) { /* No signature found yet. probably more data to come. Must handle split boundaries. */ data = content->servp; nbytes = ((int) (content->endp - data)) - (wp->boundaryLen - 1); if (nbytes > 0 && writeToFile(wp, content->servp, nbytes) < 0) { return -1; } websConsumeInput(wp, nbytes); /* Get more data */ return 0; } } data = content->servp; nbytes = (bp) ? (bp - data) : bufLen(content); if (nbytes > 0) { websConsumeInput(wp, nbytes); /* This is the CRLF before the boundary */ if (nbytes >= 2 && data[nbytes - 2] == '\r' && data[nbytes - 1] == '\n') { nbytes -= 2; } if (wp->clientFilename) { /* Write the last bit of file data and add to the list of files and define environment variables */ if (writeToFile(wp, data, nbytes) < 0) { return -1; } hashEnter(wp->files, wp->uploadVar, valueSymbol(file), 0); defineUploadVars(wp); } else { /* Normal string form data variables */ data[nbytes] = '\0'; trace(5, "uploadFilter: form[%s] = %s", wp->uploadVar, data); websDecodeUrl(wp->uploadVar, wp->uploadVar, -1); websDecodeUrl(data, data, -1); websSetVar(wp, wp->uploadVar, data); } } if (wp->clientFilename) { /* Now have all the data (we've seen the boundary) */ close(wp->upfd); wp->upfd = -1; wp->clientFilename = 0; wfree(wp->uploadTmp); wp->uploadTmp = 0; } wp->uploadState = UPLOAD_BOUNDARY; return 0; }
PUBLIC int websProcessUploadData(Webs *wp) { char *line, *nextTok; ssize len, nbytes; int done, rc; for (done = 0, line = 0; !done; ) { if (wp->uploadState == UPLOAD_BOUNDARY || wp->uploadState == UPLOAD_CONTENT_HEADER) { /* Parse the next input line */ line = wp->input.servp; if ((nextTok = memchr(line, '\n', bufLen(&wp->input))) == 0) { /* Incomplete line */ break; } *nextTok++ = '\0'; nbytes = nextTok - line; websConsumeInput(wp, nbytes); strim(line, "\r", WEBS_TRIM_END); len = strlen(line); if (line[len - 1] == '\r') { line[len - 1] = '\0'; } } switch (wp->uploadState) { case 0: if (initUpload(wp) < 0) { done++; } break; case UPLOAD_BOUNDARY: if (processContentBoundary(wp, line) < 0) { done++; } break; case UPLOAD_CONTENT_HEADER: if (processUploadHeader(wp, line) < 0) { done++; } break; case UPLOAD_CONTENT_DATA: if ((rc = processContentData(wp)) < 0) { done++; } if (bufLen(&wp->input) < wp->boundaryLen) { /* Incomplete boundary - return to get more data */ done++; } break; case UPLOAD_CONTENT_END: done++; break; } } if (!websValid(wp)) { return -1; } bufCompact(&wp->input); return 0; }