static int Seek(access_t *access, uint64_t pos) { access_sys_t *sys = access->p_sys; access->info.b_eof = false; if (vlc_http_file_seek(sys->file, pos)) return VLC_EGENERIC; return VLC_SUCCESS; }
block_t *vlc_http_file_read(struct vlc_http_file *file) { if (vlc_http_file_get_status(file) < 0) return NULL; block_t *block = vlc_http_res_read(file->resp); if (block == NULL) { /* Automatically reconnect if server supports seek */ if (vlc_http_file_can_seek(file) && vlc_http_file_seek(file, file->offset) == 0) block = vlc_http_res_read(file->resp); if (block == NULL) return NULL; } file->offset += block->i_buffer; return block; }
int main(void) { struct vlc_http_file *f; char *str; /* Request failure test */ f = vlc_http_file_create(NULL, url, ua, NULL); assert(f != NULL); vlc_http_file_seek(f, 0); assert(vlc_http_file_get_status(f) < 0); assert(vlc_http_file_get_redirect(f) == NULL); assert(vlc_http_file_get_size(f) == (uintmax_t)-1); assert(!vlc_http_file_can_seek(f)); assert(vlc_http_file_get_type(f) == NULL); assert(vlc_http_file_read(f) == NULL); vlc_http_file_destroy(f); /* Non-seekable stream test */ replies[0] = "HTTP/1.1 200 OK\r\n" "ETag: \"foobar42\"\r\n" "Content-Type: video/mpeg\r\n" "\r\n"; offset = 0; f = vlc_http_file_create(NULL, url, ua, NULL); assert(f != NULL); assert(vlc_http_file_get_status(f) == 200); assert(!vlc_http_file_can_seek(f)); assert(vlc_http_file_get_size(f) == (uintmax_t)-1); str = vlc_http_file_get_type(f); assert(str != NULL && !strcmp(str, "video/mpeg")); free(str); /* Seek failure */ replies[0] = "HTTP/1.1 200 OK\r\nETag: \"foobar42\"\r\n\r\n"; assert(vlc_http_file_seek(f, offset = 1234) < 0); vlc_http_file_destroy(f); /* Seekable file test */ replies[0] = "HTTP/1.1 206 Partial Content\r\n" "Content-Range: bytes 0-2344/2345\r\n" "ETag: W/\"foobar42\"\r\n" "\r\n"; offset = 0; f = vlc_http_file_create(NULL, url, ua, NULL); assert(f != NULL); assert(vlc_http_file_can_seek(f)); assert(vlc_http_file_get_size(f) == 2345); /* Seek success */ replies[0] = "HTTP/1.1 206 Partial Content\r\n" "Content-Range: bytes 1234-3455/3456\r\n" "ETag: W/\"foobar42\"\r\n" "\r\n"; assert(vlc_http_file_seek(f, offset = 1234) == 0); assert(vlc_http_file_can_seek(f)); assert(vlc_http_file_get_size(f) == 3456); /* Seek too far */ replies[0] = "HTTP/1.1 416 Range Not Satisfiable\r\n" "Content-Range: bytes */4567\r\n" "ETag: W/\"foobar42\"\r\n" "\r\n"; vlc_http_file_seek(f, offset = 5678); assert(vlc_http_file_can_seek(f)); assert(vlc_http_file_get_size(f) == 4567); assert(vlc_http_file_read(f) == NULL); vlc_http_file_destroy(f); /* Redirect */ replies[0] = "HTTP/1.1 301 Permanent Redirect\r\n" "Location: /somewhere/else/#here\r\n" "\r\n"; offset = 0; f = vlc_http_file_create(NULL, url, ua, NULL); assert(f != NULL); assert(!vlc_http_file_can_seek(f)); assert(vlc_http_file_get_size(f) == (uintmax_t)-1); str = vlc_http_file_get_redirect(f); assert(str != NULL && !strcmp(str, "https://www.example.com:8443/somewhere/else/")); free(str); vlc_http_file_destroy(f); /* Continuation */ replies[0] = "HTTP/1.1 100 Standby\r\n" "\r\n"; replies[1] = "HTTP/1.1 200 OK\r\n" "Content-Length: 9999\r\n" "\r\n"; offset = 0; f = vlc_http_file_create(NULL, url, ua, NULL); assert(f != NULL); assert(vlc_http_file_get_size(f) == 9999); assert(vlc_http_file_get_redirect(f) == NULL); vlc_http_file_destroy(f); /* Dummy API calls */ f = vlc_http_file_create(NULL, "ftp://localhost/foo", NULL, NULL); assert(f == NULL); return 0; }