/* return non zero if error */ static int http_open_cnx(URLContext *h, AVDictionary **options) { HTTPAuthType cur_auth_type, cur_proxy_auth_type; HTTPContext *s = h->priv_data; int location_changed, attempts = 0, redirects = 0; redo: av_dict_copy(options, s->chained_options, 0); cur_auth_type = s->auth_state.auth_type; cur_proxy_auth_type = s->auth_state.auth_type; location_changed = http_open_cnx_internal(h, options); if (location_changed < 0) goto fail; attempts++; if (s->http_code == 401) { if ((cur_auth_type == HTTP_AUTH_NONE || s->auth_state.stale) && s->auth_state.auth_type != HTTP_AUTH_NONE && attempts < 4) { ffurl_closep(&s->hd); goto redo; } else goto fail; } if (s->http_code == 407) { if ((cur_proxy_auth_type == HTTP_AUTH_NONE || s->proxy_auth_state.stale) && s->proxy_auth_state.auth_type != HTTP_AUTH_NONE && attempts < 4) { ffurl_closep(&s->hd); goto redo; } else goto fail; } if ((s->http_code == 301 || s->http_code == 302 || s->http_code == 303 || s->http_code == 307) && location_changed == 1) { /* url moved, get next */ ffurl_closep(&s->hd); if (redirects++ >= MAX_REDIRECTS) return AVERROR(EIO); /* Restart the authentication process with the new target, which * might use a different auth mechanism. */ memset(&s->auth_state, 0, sizeof(s->auth_state)); attempts = 0; location_changed = 0; goto redo; } return 0; fail: if (s->hd) ffurl_closep(&s->hd); if (location_changed < 0) return location_changed; return ff_http_averror(s->http_code, AVERROR(EIO)); }
static int http_proxy_close(URLContext *h) { HTTPContext *s = h->priv_data; if (s->hd) ffurl_closep(&s->hd); return 0; }
static int mmsh_close(URLContext *h) { MMSHContext *mmsh = (MMSHContext *)h->priv_data; MMSContext *mms = &mmsh->mms; if (mms->mms_hd) ffurl_closep(&mms->mms_hd); av_freep(&mms->streams); av_freep(&mms->asf_header); return 0; }
static int tcp_accept(URLContext *s, URLContext **c) { TCPContext *sc = s->priv_data; TCPContext *cc; int ret; av_assert0(sc->listen); if ((ret = ffurl_alloc(c, s->filename, s->flags, &s->interrupt_callback)) < 0) return ret; cc = (*c)->priv_data; ret = ff_accept(sc->fd, sc->listen_timeout, s); if (ret < 0) { ffurl_closep(c); return ret; } cc->fd = ret; return 0; }
static int http_close(URLContext *h) { int ret = 0; HTTPContext *s = h->priv_data; #if CONFIG_ZLIB inflateEnd(&s->inflate_stream); av_freep(&s->inflate_buffer); #endif /* CONFIG_ZLIB */ if (!s->end_chunked_post) /* Close the write direction by sending the end of chunked encoding. */ ret = http_shutdown(h, h->flags); if (s->hd) ffurl_closep(&s->hd); av_dict_free(&s->chained_options); return ret; }
int ffurl_close(URLContext *h) { return ffurl_closep(&h); }
static int http_proxy_open(URLContext *h, const char *uri, int flags) { HTTPContext *s = h->priv_data; char hostname[1024], hoststr[1024]; char auth[1024], pathbuf[1024], *path; char lower_url[100]; int port, ret = 0, attempts = 0; HTTPAuthType cur_auth_type; char *authstr; int new_loc; if( s->seekable == 1 ) h->is_streamed = 0; else h->is_streamed = 1; av_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port, pathbuf, sizeof(pathbuf), uri); ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL); path = pathbuf; if (*path == '/') path++; ff_url_join(lower_url, sizeof(lower_url), "tcp", NULL, hostname, port, NULL); redo: ret = ffurl_open(&s->hd, lower_url, AVIO_FLAG_READ_WRITE, &h->interrupt_callback, NULL); if (ret < 0) return ret; authstr = ff_http_auth_create_response(&s->proxy_auth_state, auth, path, "CONNECT"); snprintf(s->buffer, sizeof(s->buffer), "CONNECT %s HTTP/1.1\r\n" "Host: %s\r\n" "Connection: close\r\n" "%s%s" "\r\n", path, hoststr, authstr ? "Proxy-" : "", authstr ? authstr : ""); av_freep(&authstr); if ((ret = ffurl_write(s->hd, s->buffer, strlen(s->buffer))) < 0) goto fail; s->buf_ptr = s->buffer; s->buf_end = s->buffer; s->line_count = 0; s->filesize = -1; cur_auth_type = s->proxy_auth_state.auth_type; /* Note: This uses buffering, potentially reading more than the * HTTP header. If tunneling a protocol where the server starts * the conversation, we might buffer part of that here, too. * Reading that requires using the proper ffurl_read() function * on this URLContext, not using the fd directly (as the tls * protocol does). This shouldn't be an issue for tls though, * since the client starts the conversation there, so there * is no extra data that we might buffer up here. */ ret = http_read_header(h, &new_loc); if (ret < 0) goto fail; attempts++; if (s->http_code == 407 && (cur_auth_type == HTTP_AUTH_NONE || s->proxy_auth_state.stale) && s->proxy_auth_state.auth_type != HTTP_AUTH_NONE && attempts < 2) { ffurl_closep(&s->hd); goto redo; } if (s->http_code < 400) return 0; ret = ff_http_averror(s->http_code, AVERROR(EIO)); fail: http_proxy_close(h); return ret; }