struct vlc_http_msg *vlc_http_res_open(struct vlc_http_resource *res, void *opaque) { struct vlc_http_msg *req; retry: req = vlc_http_res_req(res, opaque); if (unlikely(req == NULL)) return NULL; struct vlc_http_msg *resp = vlc_http_mgr_request(res->manager, res->secure, res->host, res->port, req); vlc_http_msg_destroy(req); resp = vlc_http_msg_get_final(resp); if (resp == NULL) return NULL; vlc_http_msg_get_cookies(resp, vlc_http_mgr_get_jar(res->manager), res->secure, res->host, res->path); int status = vlc_http_msg_get_status(resp); if (status < 200 || status >= 599) goto fail; if (status == 406 && res->negotiate) { /* Not Acceptable: Content negotiation failed. Normally it means * one (or more) Accept or Accept-* header line does not match any * representation of the entity. So we set a flag to remove those * header lines (unless they accept everything), and retry. * In principles, it could be any header line, and the server can * pass Vary to clarify. It cannot be caused by If-*, Range, TE or the * other transfer- rather than representation-affecting header lines. */ vlc_http_msg_destroy(resp); res->negotiate = false; goto retry; } if (res->cbs->response_validate(res, resp, opaque)) goto fail; return resp; fail: vlc_http_msg_destroy(resp); return NULL; }
static struct vlc_http_msg * vlc_http_res_req(const struct vlc_http_resource *res, void *opaque) { struct vlc_http_msg *req; req = vlc_http_req_create("GET", res->secure ? "https" : "http", res->authority, res->path); if (unlikely(req == NULL)) return NULL; /* Content negotiation */ vlc_http_msg_add_header(req, "Accept", "*/*"); if (res->negotiate) { const char *lang = vlc_gettext("C"); if (!strcmp(lang, "C")) lang = "en_US"; vlc_http_msg_add_header(req, "Accept-Language", "%s", lang); } /* Authentication */ if (res->username != NULL) vlc_http_msg_add_creds_basic(req, false, res->username, res->password); /* Request context */ if (res->agent != NULL) vlc_http_msg_add_agent(req, res->agent); if (res->referrer != NULL) /* TODO: validate URL */ vlc_http_msg_add_header(req, "Referer", "%s", res->referrer); vlc_http_msg_add_cookies(req, vlc_http_mgr_get_jar(res->manager)); /* TODO: vlc_http_msg_add_header(req, "TE", "gzip, deflate"); */ if (res->cbs->request_format(res, req, opaque)) { vlc_http_msg_destroy(req); return NULL; } return req; }