Originally committed as revision 24832 to svn://svn.ffmpeg.org/ffmpeg/trunk
| ... | ... |
@@ -28,62 +28,6 @@ |
| 28 | 28 |
#include "avformat.h" |
| 29 | 29 |
#include <ctype.h> |
| 30 | 30 |
|
| 31 |
-static void parse_key_value(const char *params, |
|
| 32 |
- void (*callback_get_buf)(HTTPAuthState *state, |
|
| 33 |
- const char *key, int key_len, |
|
| 34 |
- char **dest, int *dest_len), HTTPAuthState *state) |
|
| 35 |
-{
|
|
| 36 |
- const char *ptr = params; |
|
| 37 |
- |
|
| 38 |
- /* Parse key=value pairs. */ |
|
| 39 |
- for (;;) {
|
|
| 40 |
- const char *key; |
|
| 41 |
- char *dest = NULL, *dest_end; |
|
| 42 |
- int key_len, dest_len = 0; |
|
| 43 |
- |
|
| 44 |
- /* Skip whitespace and potential commas. */ |
|
| 45 |
- while (*ptr && (isspace(*ptr) || *ptr == ',')) |
|
| 46 |
- ptr++; |
|
| 47 |
- if (!*ptr) |
|
| 48 |
- break; |
|
| 49 |
- |
|
| 50 |
- key = ptr; |
|
| 51 |
- |
|
| 52 |
- if (!(ptr = strchr(key, '='))) |
|
| 53 |
- break; |
|
| 54 |
- ptr++; |
|
| 55 |
- key_len = ptr - key; |
|
| 56 |
- |
|
| 57 |
- callback_get_buf(state, key, key_len, &dest, &dest_len); |
|
| 58 |
- dest_end = dest + dest_len - 1; |
|
| 59 |
- |
|
| 60 |
- if (*ptr == '\"') {
|
|
| 61 |
- ptr++; |
|
| 62 |
- while (*ptr && *ptr != '\"') {
|
|
| 63 |
- if (*ptr == '\\') {
|
|
| 64 |
- if (!ptr[1]) |
|
| 65 |
- break; |
|
| 66 |
- if (dest && dest < dest_end) |
|
| 67 |
- *dest++ = ptr[1]; |
|
| 68 |
- ptr += 2; |
|
| 69 |
- } else {
|
|
| 70 |
- if (dest && dest < dest_end) |
|
| 71 |
- *dest++ = *ptr; |
|
| 72 |
- ptr++; |
|
| 73 |
- } |
|
| 74 |
- } |
|
| 75 |
- if (*ptr == '\"') |
|
| 76 |
- ptr++; |
|
| 77 |
- } else {
|
|
| 78 |
- for (; *ptr && !(isspace(*ptr) || *ptr == ','); ptr++) |
|
| 79 |
- if (dest && dest < dest_end) |
|
| 80 |
- *dest++ = *ptr; |
|
| 81 |
- } |
|
| 82 |
- if (dest) |
|
| 83 |
- *dest = 0; |
|
| 84 |
- } |
|
| 85 |
-} |
|
| 86 |
- |
|
| 87 | 31 |
static void handle_basic_params(HTTPAuthState *state, const char *key, |
| 88 | 32 |
int key_len, char **dest, int *dest_len) |
| 89 | 33 |
{
|
| ... | ... |
@@ -149,18 +93,21 @@ void ff_http_auth_handle_header(HTTPAuthState *state, const char *key, |
| 149 | 149 |
state->auth_type <= HTTP_AUTH_BASIC) {
|
| 150 | 150 |
state->auth_type = HTTP_AUTH_BASIC; |
| 151 | 151 |
state->realm[0] = 0; |
| 152 |
- parse_key_value(p, handle_basic_params, state); |
|
| 152 |
+ ff_parse_key_value(p, (ff_parse_key_val_cb) handle_basic_params, |
|
| 153 |
+ state); |
|
| 153 | 154 |
} else if (av_stristart(value, "Digest ", &p) && |
| 154 | 155 |
state->auth_type <= HTTP_AUTH_DIGEST) {
|
| 155 | 156 |
state->auth_type = HTTP_AUTH_DIGEST; |
| 156 | 157 |
memset(&state->digest_params, 0, sizeof(DigestParams)); |
| 157 | 158 |
state->realm[0] = 0; |
| 158 |
- parse_key_value(p, handle_digest_params, state); |
|
| 159 |
+ ff_parse_key_value(p, (ff_parse_key_val_cb) handle_digest_params, |
|
| 160 |
+ state); |
|
| 159 | 161 |
choose_qop(state->digest_params.qop, |
| 160 | 162 |
sizeof(state->digest_params.qop)); |
| 161 | 163 |
} |
| 162 | 164 |
} else if (!strcmp(key, "Authentication-Info")) {
|
| 163 |
- parse_key_value(value, handle_digest_update, state); |
|
| 165 |
+ ff_parse_key_value(value, (ff_parse_key_val_cb) handle_digest_update, |
|
| 166 |
+ state); |
|
| 164 | 167 |
} |
| 165 | 168 |
} |
| 166 | 169 |
|
| ... | ... |
@@ -192,4 +192,28 @@ int ff_get_line(ByteIOContext *s, char *buf, int maxlen); |
| 192 | 192 |
|
| 193 | 193 |
#define SPACE_CHARS " \t\r\n" |
| 194 | 194 |
|
| 195 |
+/** |
|
| 196 |
+ * Callback function type for ff_parse_key_value. |
|
| 197 |
+ * |
|
| 198 |
+ * @param key a pointer to the key |
|
| 199 |
+ * @param key_len the number of bytes that belong to the key, including the '=' |
|
| 200 |
+ * char |
|
| 201 |
+ * @param dest return the destination pointer for the value in *dest, may |
|
| 202 |
+ * be null to ignore the value |
|
| 203 |
+ * @param dest_len the length of the *dest buffer |
|
| 204 |
+ */ |
|
| 205 |
+typedef void (*ff_parse_key_val_cb)(void *context, const char *key, |
|
| 206 |
+ int key_len, char **dest, int *dest_len); |
|
| 207 |
+/** |
|
| 208 |
+ * Parse a string with comma-separated key=value pairs. The value strings |
|
| 209 |
+ * may be quoted and may contain escaped characters within quoted strings. |
|
| 210 |
+ * |
|
| 211 |
+ * @param str the string to parse |
|
| 212 |
+ * @param callback_get_buf function that returns where to store the |
|
| 213 |
+ * unescaped value string. |
|
| 214 |
+ * @param context the opaque context pointer to pass to callback_get_buf |
|
| 215 |
+ */ |
|
| 216 |
+void ff_parse_key_value(const char *str, ff_parse_key_val_cb callback_get_buf, |
|
| 217 |
+ void *context); |
|
| 218 |
+ |
|
| 195 | 219 |
#endif /* AVFORMAT_INTERNAL_H */ |
| ... | ... |
@@ -3707,3 +3707,57 @@ int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt, |
| 3707 | 3707 |
return av_write_frame(dst, &local_pkt); |
| 3708 | 3708 |
} |
| 3709 | 3709 |
|
| 3710 |
+void ff_parse_key_value(const char *str, ff_parse_key_val_cb callback_get_buf, |
|
| 3711 |
+ void *context) |
|
| 3712 |
+{
|
|
| 3713 |
+ const char *ptr = str; |
|
| 3714 |
+ |
|
| 3715 |
+ /* Parse key=value pairs. */ |
|
| 3716 |
+ for (;;) {
|
|
| 3717 |
+ const char *key; |
|
| 3718 |
+ char *dest = NULL, *dest_end; |
|
| 3719 |
+ int key_len, dest_len = 0; |
|
| 3720 |
+ |
|
| 3721 |
+ /* Skip whitespace and potential commas. */ |
|
| 3722 |
+ while (*ptr && (isspace(*ptr) || *ptr == ',')) |
|
| 3723 |
+ ptr++; |
|
| 3724 |
+ if (!*ptr) |
|
| 3725 |
+ break; |
|
| 3726 |
+ |
|
| 3727 |
+ key = ptr; |
|
| 3728 |
+ |
|
| 3729 |
+ if (!(ptr = strchr(key, '='))) |
|
| 3730 |
+ break; |
|
| 3731 |
+ ptr++; |
|
| 3732 |
+ key_len = ptr - key; |
|
| 3733 |
+ |
|
| 3734 |
+ callback_get_buf(context, key, key_len, &dest, &dest_len); |
|
| 3735 |
+ dest_end = dest + dest_len - 1; |
|
| 3736 |
+ |
|
| 3737 |
+ if (*ptr == '\"') {
|
|
| 3738 |
+ ptr++; |
|
| 3739 |
+ while (*ptr && *ptr != '\"') {
|
|
| 3740 |
+ if (*ptr == '\\') {
|
|
| 3741 |
+ if (!ptr[1]) |
|
| 3742 |
+ break; |
|
| 3743 |
+ if (dest && dest < dest_end) |
|
| 3744 |
+ *dest++ = ptr[1]; |
|
| 3745 |
+ ptr += 2; |
|
| 3746 |
+ } else {
|
|
| 3747 |
+ if (dest && dest < dest_end) |
|
| 3748 |
+ *dest++ = *ptr; |
|
| 3749 |
+ ptr++; |
|
| 3750 |
+ } |
|
| 3751 |
+ } |
|
| 3752 |
+ if (*ptr == '\"') |
|
| 3753 |
+ ptr++; |
|
| 3754 |
+ } else {
|
|
| 3755 |
+ for (; *ptr && !(isspace(*ptr) || *ptr == ','); ptr++) |
|
| 3756 |
+ if (dest && dest < dest_end) |
|
| 3757 |
+ *dest++ = *ptr; |
|
| 3758 |
+ } |
|
| 3759 |
+ if (dest) |
|
| 3760 |
+ *dest = 0; |
|
| 3761 |
+ } |
|
| 3762 |
+} |
|
| 3763 |
+ |