diff options
author | Martin Storsjö <martin@martin.st> | 2010-03-24 22:32:05 +0000 |
---|---|---|
committer | Martin Storsjö <martin@martin.st> | 2010-03-24 22:32:05 +0000 |
commit | 9405f733d90f64ee45f47a253056c09caa7bf838 (patch) | |
tree | a8eb81a2420823882d557ac8d213fca0782088fe /libavformat/httpauth.c | |
parent | 59856b98910fcbbba5ec64540ae9b00341855b69 (diff) | |
download | ffmpeg-9405f733d90f64ee45f47a253056c09caa7bf838.tar.gz |
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.c | 132 |
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; +} + |