summaryrefslogtreecommitdiff
path: root/libavformat/httpauth.c
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2010-03-24 22:32:05 +0000
committerMartin Storsjö <martin@martin.st>2010-03-24 22:32:05 +0000
commit9405f733d90f64ee45f47a253056c09caa7bf838 (patch)
treea8eb81a2420823882d557ac8d213fca0782088fe /libavformat/httpauth.c
parent59856b98910fcbbba5ec64540ae9b00341855b69 (diff)
Split out http authentication handling into a separate file
This prepares for adding support for more authentication methods Originally committed as revision 22660 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/httpauth.c')
-rw-r--r--libavformat/httpauth.c132
1 files changed, 132 insertions, 0 deletions
diff --git a/libavformat/httpauth.c b/libavformat/httpauth.c
new file mode 100644
index 0000000000..c272de4472
--- /dev/null
+++ b/libavformat/httpauth.c
@@ -0,0 +1,132 @@
+/*
+ * HTTP authentication
+ * Copyright (c) 2010 Martin Storsjo
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "httpauth.h"
+#include "libavutil/base64.h"
+#include "libavutil/avstring.h"
+#include "avformat.h"
+#include <ctype.h>
+
+static void parse_key_value(const char *params,
+ void (*callback_get_buf)(HTTPAuthState *state,
+ const char *key, int key_len,
+ char **dest, int *dest_len), HTTPAuthState *state)
+{
+ const char *ptr = params;
+
+ /* Parse key=value pairs. */
+ for (;;) {
+ const char *key;
+ char *dest = NULL, *dest_end;
+ int key_len, dest_len = 0;
+
+ /* Skip whitespace and potential commas. */
+ while (*ptr && (isspace(*ptr) || *ptr == ','))
+ ptr++;
+ if (!*ptr)
+ break;
+
+ key = ptr;
+
+ if (!(ptr = strchr(key, '=')))
+ break;
+ ptr++;
+ key_len = ptr - key;
+
+ callback_get_buf(state, key, key_len, &dest, &dest_len);
+ dest_end = dest + dest_len - 1;
+
+ if (*ptr == '\"') {
+ ptr++;
+ while (*ptr && *ptr != '\"') {
+ if (*ptr == '\\') {
+ if (!ptr[1])
+ break;
+ if (dest && dest < dest_end)
+ *dest++ = ptr[1];
+ ptr += 2;
+ } else {
+ if (dest && dest < dest_end)
+ *dest++ = *ptr;
+ ptr++;
+ }
+ }
+ if (*ptr == '\"')
+ ptr++;
+ } else {
+ for (; *ptr && !(isspace(*ptr) || *ptr == ','); ptr++)
+ if (dest && dest < dest_end)
+ *dest++ = *ptr;
+ }
+ if (dest)
+ *dest = 0;
+ }
+}
+
+static void handle_basic_params(HTTPAuthState *state, const char *key,
+ int key_len, char **dest, int *dest_len)
+{
+ if (!strncmp(key, "realm=", key_len)) {
+ *dest = state->realm;
+ *dest_len = sizeof(state->realm);
+ }
+}
+
+void ff_http_auth_handle_header(HTTPAuthState *state, const char *key,
+ const char *value)
+{
+ if (!state)
+ return;
+
+ if (!strcmp(key, "WWW-Authenticate")) {
+ const char *p;
+ if (av_stristart(value, "Basic ", &p) &&
+ state->auth_type <= HTTP_AUTH_BASIC) {
+ state->auth_type = HTTP_AUTH_BASIC;
+ state->realm[0] = 0;
+ parse_key_value(p, handle_basic_params, state);
+ }
+ }
+}
+
+char *ff_http_auth_create_response(HTTPAuthState *state, const char *auth,
+ const char *path, const char *method)
+{
+ char *authstr = NULL;
+
+ if (!auth || !strchr(auth, ':'))
+ return NULL;
+
+ if (state->auth_type == HTTP_AUTH_BASIC) {
+ int auth_b64_len = (strlen(auth) + 2) / 3 * 4 + 1;
+ int len = auth_b64_len + 30;
+ char *ptr;
+ authstr = av_malloc(len);
+ if (!authstr)
+ return NULL;
+ snprintf(authstr, len, "Authorization: Basic ");
+ ptr = authstr + strlen(authstr);
+ av_base64_encode(ptr, auth_b64_len, auth, strlen(auth));
+ av_strlcat(ptr, "\r\n", len);
+ }
+ return authstr;
+}
+