static int read_post_data()

in tcl_cmds.c [260:393]


static int read_post_data(request_rec *r, Tcl_Interp *interp, char *boundary)
{
	int rc, lpos = 0, blen = strlen(boundary);
	char *lbuf, *ptr, *nm_var = apr_psprintf(r->pool, "%s::pram", r->filename);
	long remaining;
	
	if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)) != OK) {
		return rc;
	}
	
	remaining = r->remaining;
	lbuf = (char*) apr_palloc(r->pool, remaining + 1);

	if (ap_should_client_block(r)) {
		char buf[HUGE_STRING_LEN];
		int len_read;
		
		while ((len_read = ap_get_client_block(r, buf, sizeof(buf))) > 0) {
			memcpy(lbuf + lpos, buf, len_read);
			lpos += len_read;
		}
		
		lbuf[lpos] = '\0';
	}
	
	ptr = strstr(lbuf, boundary);
	remaining -= (ptr - lbuf - sizeof(char*));
	lbuf = ptr;
	
	while (1) {
		int i, vlen;
		char *key, *val, *filename, *eptr;
		
		if (!ptr) {
			ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "read_post_data(...): bad boundry condition in multipart/form-data");
			return DECLINED;
		}
		
		if ((*(ptr + blen + 1) == '-') && (*(ptr + blen + 1) == '-')) {
			return OK;
		}
		
		lbuf += (blen + 2);
		remaining -= (blen + 2);
		
		eptr = strstr(lbuf, "\r\n\r\n");
		
		if (!eptr) {
			ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "read_post_data(...): bad headers in multipart/form-data");
			return DECLINED;
		}
		
		ptr = lbuf;
		
		memset(eptr + 2, 0, 2);
		remaining -= (eptr - lbuf - sizeof(char*));
		lbuf = eptr + 4;
		
		while (*ptr) {
			char *xptr = ap_getword(r->pool, (const char**) &ptr, ' ');
			
			if (!strcmp("Content-Disposition:", xptr)) {
				xptr = strstr(ptr, "name=");
				
				if (!xptr) {
					ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "read_post_data(...): bad `Content-Disposition:' header");
					return DECLINED;
				}
				
				xptr += 6;
				
				for (i = 0; xptr[i] != '"'; i++) {
					;
				}
				
				key = (char*) apr_palloc(r->pool, i + 1);
				
				memcpy(key, xptr, i);
				key[i] = '\0';
				
				xptr = strstr(ptr, "filename=");
				
				if (xptr) {
					char *file_key, *file_val;
					
					xptr += 10;
					
					for (i = 0; xptr[i] != '"'; i++) {
						;
					}
					
					file_val = (char*) apr_palloc(r->pool, i + 1);
					
					memcpy(file_val, xptr, i);
					file_val[i] = '\0';
					
					file_key = apr_psprintf(r->pool, "%s_filename", key);
					
					set_varb(interp, nm_var, file_key, file_val, i);
				}
				
				break;
			}
			
			ptr = strstr(ptr, "\r\n");
			ptr += 2;
		}
		
		ptr = mstrstr(lbuf, boundary, remaining, blen);
		
		vlen = (ptr - lbuf) - sizeof(char*);
		
		if (vlen <= 0) {
			val = (char*) malloc(1);
			val[0] = '\0';
			vlen = 0;
		}
		else {
			val = (char*) malloc(vlen + 1);
			
			memcpy(val, lbuf, vlen);
			val[vlen] = '\0';
		}

		set_varb(interp, nm_var, key, val, vlen);
		
		free(val);
		
		lbuf = ptr;
		remaining -= vlen;
	}
	
	return DECLINED;
}