npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@slamb/multipart-stream

v1.0.0

Published

multipart stream parser

Downloads

13

Readme

multipart-stream-js

Javascript library to parse an HTTP multipart stream.

What's a multipart stream for?

A multipart stream is a sequence of parts in one HTTP response, each part having its own headers and body. A stream might last forever, serving parts that didn't exist at the start of the request. This is a type of "hanging GET" or Comet request.

It's a simple HTTP/1.1 way of accomplishing what otherwise might require fancier server- and client-side technologies, such as:

Never-ending multipart streams seem popular in the IP camera space:

  • Dahua IP cameras provide a multipart/x-mixed-replace stream of events such as motion detection changes. (spec)
  • Hikvision IP cameras provide a multipart/mixed stream of events, as described here.
  • wikipedia mentions that IP cameras use this format for MJPEG streams.

There's a big limitation, however, which is that browsers have fairly low limits on the number of concurrent connections. In Chrome's case, six per host.

I wrote this library as part of my own Moonfire NVR to implement live streams (a multipart stream of .mp4 media segments) and event streams. Due to the limitation above, I'm likely going to use WebSockets instead.

What is a multipart stream exactly?

A multipart response might look like this:

Content-Type: multipart/x-mixed-replace: boundary=B

--B
Content-Type: text/plain
Content-Length: 3

foo

--B
Content-Type: text/plain
Content-Length: 3

bar

and is typically paired with Transfer-Encoding: chunked or Connection: close to allow sending a response whose size is infinite or not known until the end.

I can't find a good specification. This WHATWG document describes multipart/x-mixed-replace loosely. It refers to RFC 2046 which defines multipart encodings originally used for rich emails. I don't think these HTTP multipart streams quite follow that RFC. My library currently requires:

  • Content type multipart/...; boundary=.... In MIME media type terminology, the type is multipart; the subtype may be anything. There should be exactly one parameter, boundary.
  • No preamble. That is, no arbitrary bytes to discard before the first part's boundary.
  • Zero or more newlines (to be precise: \r\n sequences) between each part and the next part's boundary.
  • A Content-Length line for each part. This is a much cleaner approach than producers attempting to choose a boundary that doesn't appear in any part and consumers having to search through the part body.
  • No extra -- suffix on the final part's boundary. In practice, all the streams I've seen only end due to error, so this point has never come up.

Please open a github issue if you encounter a multipart stream which doesn't match these requirements.

What does this library do?

It reads from from a ReadableStream as defined in the WHATWG Streams API (spec, MDN) and turns it into another ReadableStream of parts. Each part has a header and body.

It works well with the WHATWG Fetch API (spec, MDN).

Example:

import multipartStream from `.../multipart-stream.js`;

async function processStream() {
  const response = await fetch(`http://example.com/stream`);
  const reader = multipartStream(
      response.headers.get('Content-Type'),
      response.body);
  while (true) {
    const {done, value} = reader.read();
    if (done) {
      break;
    }
    const {headers, body} = value;
    ...
  }
}

Where does it work?

Modern web browsers. It's tested on recent Chrome and Firefox via Karma and Jasmine.

It doesn't work on node.js, which lacks support for WHATWG Streams. I found a github project for support but it's just a skeleton.

It uses the npm ecosystem for package management.

Development notes

Contributions welcome. There's no CI setup (yet) but each commit should be tested via:

$ npm install
$ npm test
$ npm run lint

Please follow the Google Javascript style guide.

Author

Scott Lamb <[email protected]>

License

Your choice of MIT or Apache; see LICENSE-MIT.txt or LICENSE-APACHE, respectively.