Added Active Storage support for byte ranges by tomprats · Pull Request #41437 ·...
source link: https://github.com/rails/rails/pull/41437
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Conversation
Summary
This PR allows Active Storage to have byte-range support.
I’m serving audio for a podcast using Active Storage’s proxy feature with AWS’s S3. But the audio on iOS devices weren't playing because Apple appears to (sometimes?) require byte range support. I ended up forking Rails and have been using this branch in production for a month and all seems well.
Other Information
I opened a discussion on the forum/email list and didn't receive a lot of feedback.
https://discuss.rubyonrails.org/t/byte-range-support/76791
Let me know if there's anything else I can do to help get this moving!
I've updated the branch to add support a couple more things:
- Multipart ranges - Sends multiple parts separated by headers and a boundary
- Content length - Defaults to full blob's size. When it's a single range, it gives that chunk, when it's a multiple range it gives the total of all the parts sent
- Invalid ranges - When it's only 1 range it's supposed to error to send 416. When there are valid ranges with it, it simply skips the invalid
There are a couple spots I'm not confident on:
- Content length of multipart
- Boundary - I used one fo the examples from the docs but I believe we could be randomly generating it
I won't be able to test this for a little while, but would love some feedback or help. I was planning to rebase main
back in once this was finished but let me know if you'd prefer a rebase or merge before then
I updated this from scratch due to some restructuring and changes in ActiveStorage (original commits still available in https://github.com/tomprats/rails/tree/active-storage-byte-range-backup).
Some extra changes since last time:
- Updated boundary to be generated by SecureRandom
- Added line breaks to multipart responses
- Added some new test cases for the different types of byte range requests
Some info about the boundary: I used SecureRandom because that's what's used to generate random IDs elsewhere in Rails. RFC says it can be no longer than 70 characters, but it seemed like smaller ones were often used in the examples - https://tools.ietf.org/html/rfc2046
Here are some of the other resources if anyone wants to verify what I've been going off of:
Let me know if there's anything else holding it back! I'm testing it out in a couple of projects
Learned some new things tonight. Since we're streaming, we don't need the content length (we'd either have to guess at what it might be, or make all the requests first which would negate the benefits of streaming).
I'm not sure if it's not supported by curl but I can't seem to reproduce a successful multipart curl with streaming.
I was able to produce the correct output when switching from send_stream
to send_data
. Due to byte ranges already being smaller in size, I think it would probably be beneficial to switch to send_data
. I will give this another look tomorrow and potentially update the PR with that solution.
I was trying to figure out a potential issue with content-length:
- Looks like it might be getting removed still due to something magical (does not show up in curl and produces a warning in the server's terminal).
- The value of the header in the test does not correspond to what I set it in the proxy controller.
send_data
might technically still be streaming, but differently than send_stream
. Or rack or rails might be doing something I can't figure out. Something like this but then I don't know why it's still in the test.
Here's a warning the server spits out when I curl the proxy. I cannot find the origin of what is producing the warning:
[2021-04-22 23:41:14] WARN Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true
All in all, I think I've done the best I can and maybe these content length issues are meaningless. It appears to work in my app. I think I'm done until I receive some feedback. Thanks for coming to my TED talk.
Copy link
arpu commented 24 days ago
any hope to get this in for Rails 7.0 ?
Sorry for the wait, I was on vacation for a week. Going to take a look at this tonight or this weekend
- Updated everything with your feedback @rafaelfranca
- Re-squashed it down into 1 commit again
@tomprats perfect, thank you!
No one assigned
None yet
No milestone
Successfully merging this pull request may close these issues.
None yet
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK