Exemplo n.º 1
0
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;
		}
	}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
/*
 * 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);
}