[sheepdog] [PATCH 1/2] sheep/http: add range support for swift insterface

Liu Yuan namei.unix at gmail.com
Thu Jan 16 15:50:10 CET 2014


On Thu, Jan 16, 2014 at 05:03:46PM +0800, Robin Dong wrote:
> From: Robin Dong <sanbai at taobao.com>
> 
> In swift spec, "Range: bytes=13-15" in http header means "read the three bytes
> of data after a 13-byte offset". We add this support by parsing http header and
> read specific bytes in range.
> 
> We don't support multi-ranges at present.
> 
> Signed-off-by: Robin Dong <sanbai at taobao.com>
> ---
>  sheep/http/http.c | 30 ++++++++++++++++++++++++++++++
>  sheep/http/http.h |  1 +
>  sheep/http/kv.c   | 41 ++++++++++++++++++++++++++++++++---------
>  3 files changed, 63 insertions(+), 9 deletions(-)
> 
> diff --git a/sheep/http/http.c b/sheep/http/http.c
> index 165c818..16558b1 100644
> --- a/sheep/http/http.c
> +++ b/sheep/http/http.c
> @@ -169,10 +169,40 @@ static int request_init_operation(struct http_request *req)
>  	req->uri = FCGX_GetParam("DOCUMENT_URI", env);
>  	if (!req->uri)
>  		return BAD_REQUEST;
> +	p = FCGX_GetParam("HTTP_RANGE", env);
> +	if (p && p[0] != '\0') {
> +		const char prefix[] = "bytes=";
> +		char *left, *right, num[64];
> +		left = strstr(p, prefix);
> +		if (!p)
> +			goto invalid_range;
> +		right = strchr(left, '-');
> +		strncpy(num, left + sizeof(prefix) - 1, right - left);
> +		req->range[0] = strtoll(num, &endp, 10);
> +		if (num == endp)
> +			goto invalid_range;
> +		strcpy(num, right + 1);
> +		/*
> +		 * In swift spec, the second number of RANGE should be included
> +		 * which means [num1, num2], but our common means for read and
> +		 * write data by 'offset' and 'len' is [num1, num2), so we
> +		 * should add 1 to num2.
> +		 */
> +		req->range[1] = strtoll(num, &endp, 10) + 1;
> +		if (num == endp)
> +			goto invalid_range;
> +		if (req->range[1] <= req->range[0])
> +			goto invalid_range;
> +		sd_debug("HTTP_RANGE: %lu %lu", req->range[0], req->range[1]);
> +	}
>  
>  	req->status = UNKNOWN;
>  
>  	return OK;
> +
> +invalid_range:
> +	sd_err("invalid range %s", p);
> +	return BAD_REQUEST;
>  }
>  
>  static int http_init_request(struct http_request *req)
> diff --git a/sheep/http/http.h b/sheep/http/http.h
> index 20246dc..7cf3916 100644
> --- a/sheep/http/http.h
> +++ b/sheep/http/http.h
> @@ -48,6 +48,7 @@ struct http_request {
>  	enum http_opcode opcode;
>  	enum http_status status;
>  	uint64_t data_length;
> +	uint64_t range[2];

I think uint64_t offset; would be enough. 'range' can be translated into
data_length and offset easily, which is more internal API friendly.

Thanks
Yuan



More information about the sheepdog mailing list