| defmodule AttachmentRangesTest do |
| use CouchTestCase |
| |
| @moduletag :attachments |
| |
| @moduledoc """ |
| Test CouchDB attachment range requests |
| This is a port of the attachment_ranges.js suite |
| """ |
| |
| @tag :with_db |
| test "manages attachment range requests successfully", context do |
| db_name = context[:db_name] |
| |
| bin_att_doc = %{ |
| _id: "bin_doc", |
| _attachments: %{ |
| "foo.txt": %{ |
| content_type: "application/octet-stream", |
| data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ=" |
| } |
| } |
| } |
| |
| create_doc(db_name, bin_att_doc) |
| # Fetching the whole entity is a 206 |
| resp = |
| Couch.get( |
| "/#{db_name}/bin_doc/foo.txt", |
| headers: [Range: "bytes=0-28"] |
| ) |
| |
| assert(resp.status_code == 206) |
| assert resp.body == "This is a base64 encoded text" |
| assert resp.headers["Content-Range"] == "bytes 0-28/29" |
| assert resp.headers["Content-Length"] == "29" |
| |
| # Fetch the whole entity without an end offset is a 200 |
| resp = |
| Couch.get( |
| "/#{db_name}/bin_doc/foo.txt", |
| headers: [Range: "bytes=0-"] |
| ) |
| |
| assert(resp.status_code == 200) |
| assert resp.body == "This is a base64 encoded text" |
| assert resp.headers["Content-Range"] == nil |
| assert resp.headers["Content-Length"] == "29" |
| |
| # Even if you ask multiple times. |
| resp = |
| Couch.get( |
| "/#{db_name}/bin_doc/foo.txt", |
| headers: [Range: "bytes=0-,0-,0-"] |
| ) |
| |
| assert(resp.status_code == 200) |
| |
| # Badly formed range header is a 200 |
| resp = |
| Couch.get( |
| "/#{db_name}/bin_doc/foo.txt", |
| headers: [Range: "bytes:0-"] |
| ) |
| |
| assert(resp.status_code == 200) |
| |
| # Fetch the end of an entity without an end offset is a 206 |
| resp = |
| Couch.get( |
| "/#{db_name}/bin_doc/foo.txt", |
| headers: [Range: "bytes=2-"] |
| ) |
| |
| assert(resp.status_code == 206) |
| assert resp.body == "is is a base64 encoded text" |
| assert resp.headers["Content-Range"] == "bytes 2-28/29" |
| assert resp.headers["Content-Length"] == "27" |
| |
| # Fetch first part of entity is a 206 |
| resp = |
| Couch.get( |
| "/#{db_name}/bin_doc/foo.txt", |
| headers: [Range: "bytes=0-3"] |
| ) |
| |
| assert(resp.status_code == 206) |
| assert resp.body == "This" |
| assert resp.headers["Content-Range"] == "bytes 0-3/29" |
| assert resp.headers["Content-Length"] == "4" |
| |
| # Fetch middle of entity is also a 206 |
| resp = |
| Couch.get( |
| "/#{db_name}/bin_doc/foo.txt", |
| headers: [Range: "bytes=10-15"] |
| ) |
| |
| assert(resp.status_code == 206) |
| assert resp.body == "base64" |
| assert resp.headers["Content-Range"] == "bytes 10-15/29" |
| assert resp.headers["Content-Length"] == "6" |
| |
| # Fetch end of entity is also a 206 |
| resp = |
| Couch.get( |
| "/#{db_name}/bin_doc/foo.txt", |
| headers: [Range: "bytes=-3"] |
| ) |
| |
| assert(resp.status_code == 206) |
| assert resp.body == "ext" |
| assert resp.headers["Content-Range"] == "bytes 26-28/29" |
| assert resp.headers["Content-Length"] == "3" |
| |
| # backward range is 416 |
| resp = |
| Couch.get( |
| "/#{db_name}/bin_doc/foo.txt", |
| headers: [Range: "bytes=5-3"] |
| ) |
| |
| assert(resp.status_code == 416) |
| |
| # range completely outside of entity is 416 |
| resp = |
| Couch.get( |
| "/#{db_name}/bin_doc/foo.txt", |
| headers: [Range: "bytes=300-310"] |
| ) |
| |
| assert(resp.status_code == 416) |
| |
| # We ignore a Range header with too many ranges |
| resp = |
| Couch.get( |
| "/#{db_name}/bin_doc/foo.txt", |
| headers: [Range: "bytes=0-1,0-1,0-1,0-1,0-1,0-1,0-1,0-1,0-1,0-1"] |
| ) |
| |
| assert(resp.status_code == 200) |
| end |
| end |