Browse code

Make parse_key_value from httpauth a common lavf internal function

Originally committed as revision 24832 to svn://svn.ffmpeg.org/ffmpeg/trunk

Martin Storsjö authored on 2010/08/19 23:49:53
Showing 3 changed files
... ...
@@ -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
+