Exemple #1
0
char *php_http_url_authority_to_string(const php_http_url_t *url, char **url_str, size_t *url_len)
{
	php_http_buffer_t buf;

	php_http_buffer_init(&buf);

	if (url->user && *url->user) {
		php_http_buffer_appendl(&buf, url->user);
		if (url->pass && *url->pass) {
			php_http_buffer_appends(&buf, ":");
			php_http_buffer_appendl(&buf, url->pass);
		}
		php_http_buffer_appends(&buf, "@");
	}

	if (url->host && *url->host) {
		php_http_buffer_appendl(&buf, url->host);
		if (url->port) {
			php_http_buffer_appendf(&buf, ":%hu", url->port);
		}
	}

	php_http_buffer_shrink(&buf);
	php_http_buffer_fix(&buf);

	if (url_len) {
		*url_len = buf.used;
	}

	if (url_str) {
		*url_str = buf.data;
	}

	return buf.data;
}
Exemple #2
0
static PHP_HTTP_FILTER_FUNCTION(chunked_decode)
{
	int out_avail = 0;
	php_stream_bucket *ptr, *nxt;
	PHP_HTTP_FILTER_BUFFER(chunked_decode) *buffer = Z_PTR(this->abstract);
	
	if (bytes_consumed) {
		*bytes_consumed = 0;
	}
	
	/* fetch available bucket data */
	for (ptr = buckets_in->head; ptr; ptr = nxt) {
		if (bytes_consumed) {
			*bytes_consumed += ptr->buflen;
		}

		if (PHP_HTTP_BUFFER_NOMEM == php_http_buffer_append(PHP_HTTP_BUFFER(buffer), ptr->buf, ptr->buflen)) {
			return PSFS_ERR_FATAL;
		}

		nxt = ptr->next;
		php_stream_bucket_unlink(ptr);
		php_stream_bucket_delref(ptr);
	}
	
	if (!php_http_buffer_fix(PHP_HTTP_BUFFER(buffer))) {
		return PSFS_ERR_FATAL;
	}

	/* we have data in our buffer */
	while (PHP_HTTP_BUFFER(buffer)->used) {
	
		/* we already know the size of the chunk and are waiting for data */
		if (buffer->hexlen) {
		
			/* not enough data buffered */
			if (PHP_HTTP_BUFFER(buffer)->used < buffer->hexlen) {
			
				/* flush anyway? */
				if (flags & PSFS_FLAG_FLUSH_INC) {
				
					/* flush all data (should only be chunk data) */
					out_avail = 1;
					NEW_BUCKET(PHP_HTTP_BUFFER(buffer)->data, PHP_HTTP_BUFFER(buffer)->used);
					
					/* waiting for less data now */
					buffer->hexlen -= PHP_HTTP_BUFFER(buffer)->used;
					/* no more buffered data */
					php_http_buffer_reset(PHP_HTTP_BUFFER(buffer));
					/* break */
				} 
				
				/* we have too less data and don't need to flush */
				else {
					break;
				}
			} 
			
			/* we seem to have all data of the chunk */
			else {
				out_avail = 1;
				NEW_BUCKET(PHP_HTTP_BUFFER(buffer)->data, buffer->hexlen);
				
				/* remove outgoing data from the buffer */
				php_http_buffer_cut(PHP_HTTP_BUFFER(buffer), 0, buffer->hexlen);
				/* reset hexlen */
				buffer->hexlen = 0;
				/* continue */
			}
		} 
		
		/* we don't know the length of the chunk yet */
		else {
			size_t off = 0;
			
			/* ignore preceeding CRLFs (too loose?) */
			while (off < PHP_HTTP_BUFFER(buffer)->used && (
					PHP_HTTP_BUFFER(buffer)->data[off] == '\n' || 
					PHP_HTTP_BUFFER(buffer)->data[off] == '\r')) {
				++off;
			}
			if (off) {
				php_http_buffer_cut(PHP_HTTP_BUFFER(buffer), 0, off);
			}
			
			/* still data there? */
			if (PHP_HTTP_BUFFER(buffer)->used) {
				int eollen;
				const char *eolstr;
				
				/* we need eol, so we can be sure we have all hex digits */
				php_http_buffer_fix(PHP_HTTP_BUFFER(buffer));
				if ((eolstr = php_http_locate_bin_eol(PHP_HTTP_BUFFER(buffer)->data, PHP_HTTP_BUFFER(buffer)->used, &eollen))) {
					char *stop = NULL;
					
					/* read in chunk size */
					buffer->hexlen = strtoul(PHP_HTTP_BUFFER(buffer)->data, &stop, 16);
					
					/*	if strtoul() stops at the beginning of the buffered data
						there's something oddly wrong, i.e. bad input */
					if (stop == PHP_HTTP_BUFFER(buffer)->data) {
						return PSFS_ERR_FATAL;
					}
					
					/* cut out <chunk size hex><chunk extension><eol> */
					php_http_buffer_cut(PHP_HTTP_BUFFER(buffer), 0, eolstr + eollen - PHP_HTTP_BUFFER(buffer)->data);
					/* buffer->hexlen is 0 now or contains the size of the next chunk */
					if (!buffer->hexlen) {
						php_stream_notify_info(PHP_STREAM_CONTEXT(stream), PHP_STREAM_NOTIFY_COMPLETED, NULL, 0);
						break;
					}
					/* continue */
				} else {
					/* we have not enough data buffered to read in chunk size */
					break;
				}
			}
			/* break */
		}
	}
	
	/* flush before close, but only if we are already waiting for more data */
	if (PHP_HTTP_FILTER_IS_CLOSING(stream, flags) && buffer->hexlen && PHP_HTTP_BUFFER(buffer)->used) {
		out_avail = 1;
		NEW_BUCKET(PHP_HTTP_BUFFER(buffer)->data, PHP_HTTP_BUFFER(buffer)->used);
		php_http_buffer_reset(PHP_HTTP_BUFFER(buffer));
		buffer->hexlen = 0;
	}
	
	return out_avail ? PSFS_PASS_ON : PSFS_FEED_ME;
}
Exemple #3
0
char *php_http_url_to_string(const php_http_url_t *url, char **url_str, size_t *url_len, zend_bool persistent)
{
	php_http_buffer_t buf;

	php_http_buffer_init_ex(&buf, PHP_HTTP_BUFFER_DEFAULT_SIZE, persistent ?
			PHP_HTTP_BUFFER_INIT_PERSISTENT : 0);

	if (url->scheme && *url->scheme) {
		php_http_buffer_appendl(&buf, url->scheme);
		php_http_buffer_appends(&buf, "://");
	} else if ((url->user && *url->user) || (url->host && *url->host)) {
		php_http_buffer_appends(&buf, "//");
	}

	if (url->user && *url->user) {
		php_http_buffer_appendl(&buf, url->user);
		if (url->pass && *url->pass) {
			php_http_buffer_appends(&buf, ":");
			php_http_buffer_appendl(&buf, url->pass);
		}
		php_http_buffer_appends(&buf, "@");
	}

	if (url->host && *url->host) {
		php_http_buffer_appendl(&buf, url->host);
		if (url->port) {
			php_http_buffer_appendf(&buf, ":%hu", url->port);
		}
	}

	if (url->path && *url->path) {
		if (*url->path != '/') {
			php_http_buffer_appends(&buf, "/");
		}
		php_http_buffer_appendl(&buf, url->path);
	} else if (buf.used) {
		php_http_buffer_appends(&buf, "/");
	}

	if (url->query && *url->query) {
		php_http_buffer_appends(&buf, "?");
		php_http_buffer_appendl(&buf, url->query);
	}

	if (url->fragment && *url->fragment) {
		php_http_buffer_appends(&buf, "#");
		php_http_buffer_appendl(&buf, url->fragment);
	}

	php_http_buffer_shrink(&buf);
	php_http_buffer_fix(&buf);

	if (url_len) {
		*url_len = buf.used;
	}

	if (url_str) {
		*url_str = buf.data;
	}

	return buf.data;
}