[FFmpeg-devel] [PATCH] Add support for digest auth in the http and rtsp protocols
Ronald S. Bultje
rsbultje
Wed Mar 24 21:53:07 CET 2010
Hi,
On Wed, Mar 24, 2010 at 4:17 PM, Martin Storsj? <martin at martin.st> wrote:
> New series attached, hopefully taking all comments into account.
Let's optimize that value-parsing a bit. Let me know if I'm going too
far or if it's ugly.
> +static char *parse_value(char *value) {
> + char *inptr = value;
> + char *outptr = value;
> + if (*inptr != '"') {
> + while (*inptr && *inptr != ' ' && *inptr != ',')
> + inptr++;
> + if (*inptr) {
> + *inptr = '\0';
> + return inptr + 1;
> + }
> + return inptr;
> + }
> + inptr++;
> + while (*inptr && *inptr != '"') {
> + if (*inptr == '\\') {
> + if (!inptr[1]) {
> + inptr++;
> + break;
> + }
> + *outptr++ = inptr[1];
> + inptr += 2;
> + } else {
> + *outptr++ = *inptr++;
> + }
> + }
> + if (*inptr == '"')
> + inptr++;
> + *outptr = '\0';
> + return inptr;
> +}
[..]
> + /* Parse key=value pairs. */
> + while (*ptr) {
> + char *key;
> + char *value;
> + char *equals;
> +
> + /* Skip whitespace and potential commas. */
> + while (*ptr && (isspace(*ptr) || *ptr == ','))
> + ptr++;
> +
> + if (!*ptr)
> + break;
>
> + key = ptr;
> +
> + equals = strchr(ptr, '=');
> + if (!equals)
> + break;
> + *equals = '\0';
> +
> + value = equals + 1;
> + ptr = parse_value(value);
> +
> + callback(ctx, key, value);
> + }
Let's see? Can you use something like this to prevent all the dups?
Perhaps a little ugly and buggy but you'll get the point.
for (;;) { <- you already check if (*ptr) in the loop
char *dest = NULL, *dest_end;
int dest_len, len;
while (*ptr && (isspace(*value) || *value == ','))
ptr++;
if (!*ptr)
break;
key = ptr;
if (!(ptr = strchr(key, '=;)))
break;
ptr++;
len = ptr - key;
/* find dest */
callback_get_buf(&dest, &dest_len);
dest_end = dest + dest_len - 1; // leave one value for terminating '\0'
assert(dest_end > dest); // assure enough space is available for
at least a '\0'
/* put value */
#define put_escaped_char(dst, end, src) \
do { \
if (ptr[0] == '\\' && ptr[1]) { \
if (dest && dest_end < dest) \
*dest++ = ptr[1]; \
ptr += 2; \
} else { \
if (dest && dest_end < dest) \
*dest++ = *ptr; \
ptr++; \
} \
} while (0)
if (*ptr == '\"') {
ptr++;
while (!(ptr[-1] != '\\' && ptr[0] == '\"'))
put_escaped_char(dest, dest_end, ptr);
} else {
while (!(ptr[-1] != '\\' && (isspace(ptr[0]) || ptr[0] == ',')))
put_escaped_char(dest, dest_end, ptr);
}
}
The implementation of callback_dest_buf() should be self-evident.
> +void ff_http_auth_handle_header(HTTPAuthState *state, const char *key,
> + const char *value)
[..]
> + if (av_stristart(value, "Basic ", &p)) {
> + char *copy;
> + if (state->auth_type > HTTP_AUTH_BASIC)
> + return;
if (av_stristart() && state->auth_type <= HTTP_AUTH_BASIC)
> + state->auth_type = HTTP_AUTH_BASIC;
> + state->realm[0] = '\0';
> + copy = av_strdup(p);
> + if (!copy)
> + return;
> + parse_key_value(copy, handle_basic_params, state);
Using the above code, no copy should be necessary.
> +static void handle_basic_params(void *ctx, char *key, char *value)
> +{
> + HTTPAuthState *state = ctx;
Why void?
> +static void parse_key_value(char *params,
> + void (*callback)(void *ctx, char *key, char *value),
> + void *ctx)
Again void.
Ronald
More information about the ffmpeg-devel
mailing list