extern char inner_req_buff[1024]; extern int middle_segment; //Brad add for update content length int req_format_write(request *req, char *format, ...) { int bob; va_list args; char temp[1024]; if (!req || !format) return 0; va_start(args, format); vsnprintf(temp, sizeof(temp), format, args); va_end(args); bob = strlen(temp); if ((void*)req == (void*)(&inner_req)) { strcpy(inner_req_buff, temp); } else { #ifndef SUPPORT_ASP if ((bob+req->buffer_end) > BUFFER_SIZE) bob = BUFFER_SIZE - req->buffer_end; #else while ((bob+req->buffer_end+10) > req->max_buffer_size) { //Brad modify int ret; ret = allocNewBuffer(req); if (ret==FAILED) { bob = BUFFER_SIZE - req->buffer_end; break; } } #endif middle_segment = middle_segment + bob; //brad add for update exact length of asp file if (bob > 0) { memcpy((req->buffer+req->buffer_end), temp, bob); req->buffer_end += bob; } }
int init_get2(request * req) { int data_fd; //Brad add begin for update content length char *content_length_orig1; char *content_length_orig2; int orig_char_length=0; int exact_char_length=0; int byte_shift=0; int exact_size=0; int total_length_shift=0; char *exact_content=NULL; int head_offset=0; int first_offset=0; int antecedent_segment=0; int subsequent_segment=0; //Brad add end for update content length #ifdef GUNZIP char buf[MAX_PATH_LENGTH]; #endif struct stat statbuf; SQUASH_KA(req); complete_env(req); middle_segment=0; req->cgi_env[req->cgi_env_index] = NULL; /* terminate cgi env */ if ((strstr(req->request_uri,".htm")==NULL) && (strstr(req->request_uri,".asp")==NULL)) { return 1; } data_fd = open(req->pathname, O_RDONLY); if (data_fd == -1) { /* cannot open */ #ifdef GUNZIP sprintf(buf, "%s.gz", req->pathname); data_fd = open(buf, O_RDONLY); if (data_fd == -1) { #endif int errno_save = errno; log_error_doc(req); errno = errno_save; #if 0 perror("document open"); #endif // syslog(LOG_ERR, "Error opening %s for %s: %s\n", req->pathname, // req->remote_ip_addr, strerror(errno_save)); errno = errno_save; if (errno == ENOENT) send_r_not_found(req); else if (errno == EACCES) send_r_forbidden(req); else send_r_bad_request(req); return 0; #ifdef GUNZIP } close(data_fd); req->response_status = R_REQUEST_OK; if (!req->simple) { req_write(req, "HTTP/1.0 200 OK-GUNZIP\r\n"); print_http_headers(req); print_content_type(req); print_last_modified(req); req_write(req, "\r\n"); req_flush(req); } if (req->method == M_HEAD) return 0; if (req->pathname) free(req->pathname); req->pathname = strdup(buf); return init_cgi(req); /* 1 - OK, 2 - die */ #endif } fstat(data_fd, &statbuf); if (S_ISDIR(statbuf.st_mode)) { close(data_fd); /* close dir */ if (req->pathname[strlen(req->pathname) - 1] != '/') { char buffer[3 * MAX_PATH_LENGTH + 128]; if (server_port != 80) sprintf(buffer, "http://%s:%d%s/", req->host?req->host:server_name, server_port, req->request_uri); else sprintf(buffer, "http://%s%s/", req->host?req->host:server_name, req->request_uri); send_redirect_perm(req, buffer); return 0; } data_fd = get_dir(req, &statbuf); /* updates statbuf */ if (data_fd == -1) { /* couldn't do it */ return 0; /* errors reported by get_dir */ } else if (data_fd == 0) { return 1; } } //start modify here : tony #if 0 if (req->if_modified_since && !modified_since(&(statbuf.st_mtime), req->if_modified_since)) { send_r_not_modified(req); close(data_fd); return 0; } #endif req->filesize = statbuf.st_size; // req->last_modified = statbuf.st_mtime; if (req->method == M_HEAD) { send_r_request_ok(req); close(data_fd); return 0; } /* MAP_OPTIONS: see compat.h */ req->data_mem = mmap(0, req->filesize, #ifdef USE_NLS PROT_READ|PROT_WRITE #else PROT_READ #endif , MAP_OPTIONS,data_fd, 0); close(data_fd); /* close data file */ if ((long) req->data_mem == -1) { boa_perror(req, "mmap"); return 0; } send_r_request_ok(req); /* All's well */ { //parse and send asp page char *left,*right,*last_right=req->data_mem; int bob; first_offset=req->buffer_end; //Brad add for update content length while (1) { left=strstr(last_right,"<%"); if (left!=NULL) right=strstr(left,"%>"); if ((left!=NULL) && (right!=NULL)) { bob=(unsigned int)left-(unsigned int)last_right; #ifdef SUPPORT_ASP while((bob+req->buffer_end+10)>(req->max_buffer_size)) { //Brad modify int ret; ret=allocNewBuffer(req); if (ret==-1) { bob=req->max_buffer_size- req->buffer_end; printf("will break\n"); break; } } #endif antecedent_segment =antecedent_segment+bob; //Brad add for update content length if (bob>=0) { memcpy(req->buffer + req->buffer_end, req->data_mem + req->filepos, bob); last_right=right+2; req->buffer_end += bob; req->filepos += (bob+(unsigned int)last_right-(unsigned int)left); handleScript(req,left,right); } } else { bob=(unsigned int)req->data_mem+req->filesize-(unsigned int)last_right; #ifdef SUPPORT_ASP while((bob+req->buffer_end+10)>req->max_buffer_size) { //Brad modify int ret; ret=allocNewBuffer(req); if (ret==-1) { bob=req->max_buffer_size- req->buffer_end; break; } } #endif subsequent_segment = subsequent_segment+bob; //Brad add for update content length if (bob > 0) { memcpy(req->buffer + req->buffer_end, req->data_mem + req->filepos, bob); req->buffer_end += bob; req->filepos += bob; } break; } } } //Brad add begin for update content length exact_content = req->buffer+first_offset; exact_size = antecedent_segment+middle_segment+subsequent_segment; //fprintf(stderr, "the exact total length of asp file=%d\n", exact_size); content_length_orig1 = strstr(req->buffer, "Content-Length:"); content_length_orig2 = strstr(content_length_orig1, "\r\n"); content_length_orig1 = content_length_orig1 + strlen("Content-Length: "); orig_char_length = content_length_orig2 - content_length_orig1; //fprintf(stderr, "the orig_char_length=%d\n", orig_char_length); exact_char_length = strlen(simple_itoa(exact_size)); //fprintf(stderr, "the exact_char_length=%d\n", exact_char_length); if(orig_char_length == exact_char_length) { //fprintf(stderr, "Update the content length with the same char length!\n"); memcpy(content_length_orig1, simple_itoa(exact_size),exact_char_length); }else if(orig_char_length < exact_char_length) { //fprintf(stderr, " Update the content length with shift to later bytes!\n"); byte_shift = exact_char_length - orig_char_length; head_offset = first_offset- (content_length_orig2 - req->buffer); total_length_shift = head_offset+exact_size; memmove((content_length_orig2+byte_shift), content_length_orig2, total_length_shift); memcpy(content_length_orig1, simple_itoa(exact_size),exact_char_length); req->buffer_end = req->buffer_end+byte_shift; }else { //fprintf(stderr, "Update the content length with shift to preceding bytes!\n"); byte_shift = orig_char_length - exact_char_length; head_offset = first_offset- (content_length_orig2 - req->buffer); total_length_shift = head_offset+exact_size; memmove((content_length_orig2-byte_shift), content_length_orig2, total_length_shift); memcpy(content_length_orig1, simple_itoa(exact_size),exact_char_length); req->buffer_end = req->buffer_end-byte_shift; } //Brad add end for update content length if (req->filepos == req->filesize) { // req->status = CLOSE; return 0; /* done! */ } /* We lose statbuf here, so make sure response has been sent */ return 1; }
/* * Get a buffer of the type and parity specified by flags, having at least * as much free space as indicated by needSpace. We use the lastUsedPages * cache to assign the same buffer previously requested when possible. * The returned buffer is already pinned and exclusive-locked. * * *isNew is set true if the page was initialized here, false if it was * already valid. */ Buffer SpGistGetBuffer(Relation index, int flags, int needSpace, bool *isNew) { SpGistCache *cache = spgGetCache(index); SpGistLastUsedPage *lup; /* Bail out if even an empty page wouldn't meet the demand */ if (needSpace > SPGIST_PAGE_CAPACITY) elog(ERROR, "desired SPGiST tuple size is too big"); /* * If possible, increase the space request to include relation's * fillfactor. This ensures that when we add unrelated tuples to a page, * we try to keep 100-fillfactor% available for adding tuples that are * related to the ones already on it. But fillfactor mustn't cause an * error for requests that would otherwise be legal. */ needSpace += RelationGetTargetPageFreeSpace(index, SPGIST_DEFAULT_FILLFACTOR); needSpace = Min(needSpace, SPGIST_PAGE_CAPACITY); /* Get the cache entry for this flags setting */ lup = GET_LUP(cache, flags); /* If we have nothing cached, just turn it over to allocNewBuffer */ if (lup->blkno == InvalidBlockNumber) { *isNew = true; return allocNewBuffer(index, flags); } /* fixed pages should never be in cache */ Assert(!SpGistBlockIsFixed(lup->blkno)); /* If cached freeSpace isn't enough, don't bother looking at the page */ if (lup->freeSpace >= needSpace) { Buffer buffer; Page page; buffer = ReadBuffer(index, lup->blkno); if (!ConditionalLockBuffer(buffer)) { /* * buffer is locked by another process, so return a new buffer */ ReleaseBuffer(buffer); *isNew = true; return allocNewBuffer(index, flags); } page = BufferGetPage(buffer); if (PageIsNew(page) || SpGistPageIsDeleted(page) || PageIsEmpty(page)) { /* OK to initialize the page */ uint16 pageflags = 0; if (GBUF_REQ_LEAF(flags)) pageflags |= SPGIST_LEAF; if (GBUF_REQ_NULLS(flags)) pageflags |= SPGIST_NULLS; SpGistInitBuffer(buffer, pageflags); lup->freeSpace = PageGetExactFreeSpace(page) - needSpace; *isNew = true; return buffer; } /* * Check that page is of right type and has enough space. We must * recheck this since our cache isn't necessarily up to date. */ if ((GBUF_REQ_LEAF(flags) ? SpGistPageIsLeaf(page) : !SpGistPageIsLeaf(page)) && (GBUF_REQ_NULLS(flags) ? SpGistPageStoresNulls(page) : !SpGistPageStoresNulls(page))) { int freeSpace = PageGetExactFreeSpace(page); if (freeSpace >= needSpace) { /* Success, update freespace info and return the buffer */ lup->freeSpace = freeSpace - needSpace; *isNew = false; return buffer; } } /* * fallback to allocation of new buffer */ UnlockReleaseBuffer(buffer); } /* No success with cache, so return a new buffer */ *isNew = true; return allocNewBuffer(index, flags); }