dataurl

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 28, 2023 License: GPL-3.0 Imports: 10 Imported by: 0

README

dataurl

Go Reference

codeberg.org/piman/dataurl encodes and decodes data using the RFC 2397 “data” URL scheme.

Data URLs are used to embed data inline in URLs, so they do not need to be retrieved via a remote server. They can be used to optimize round-trips for small data on websites, or pass data already in hand directly to something normally expecting a URL.

Three main components are provided,

  • Builder, to create data URLs from data streams
  • Reader, to read data from data URLs
  • Transport, an http.RoundTripper to handle requests to data URLs

License

Copyright 2023 Joe Wreschnig

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

Documentation

Overview

Package dataurl encodes and decodes data using the RFC 2397 “data” URL scheme.

Data URLs are used to embed data inline in URLs, so they do not need to be retrieved via a remote server. They can be used to optimize round-trips for small data on websites, or pass data already in hand directly to something normally expecting a URL.

Example (Transport)
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"

	"codeberg.org/piman/dataurl"
)

var (
	transport = http.DefaultTransport.(*http.Transport).Clone()
	client    = http.Client{Transport: transport}
)

func init() {
	transport.RegisterProtocol("data", dataurl.Transport)
}

func main() {
	resp, _ := client.Get("data:;base64,QSBicmllZiBub3Rl")

	var sb strings.Builder
	_, _ = io.Copy(&sb, resp.Body)
	_ = resp.Body.Close()

	fmt.Println("Content-Type:", resp.Header.Get("Content-Type"))
	fmt.Println("Content-Length:", resp.ContentLength)
	fmt.Println("\n" + sb.String())
}
Output:

Content-Type: text/plain; charset=US-ASCII
Content-Length: 12

A brief note

Index

Examples

Constants

This section is empty.

Variables

View Source
var Transport http.RoundTripper = roundTrip{}

Transport handles requests for data scheme URLs.

Requests to data URLs will respond to HEAD (with http.StatusOK, the ContentLength and Content-Type), GET (with that plus the decoded body), and OPTIONS (with http.StatusNoContent and allowing these methods) requests. Otherwise, you will receive an http.StatusMethodNotAllowed response.

If the data URL is invalid, you may receive an error immediately (if the problem was in its headers) or later while reading the body (if due to mis-encoded data).

Functions

This section is empty.

Types

type Builder

type Builder struct {
	// contains filtered or unexported fields
}

A Builder constructs a data URL. The zero value is ready to use, and will result in a base64-encoded data URL.

Do not copy a non-zero Builder.

Example
package main

import (
	"fmt"

	"codeberg.org/piman/dataurl"
)

func main() {
	var w dataurl.Builder
	w.PercentEncode()
	_ = w.WriteMediaType("application/octet-stream", nil)
	_, _ = w.Write([]byte{0, 1, 2, 3, 4})
	w.Close()
	fmt.Println(w.URL())
}
Output:

data:application/octet-stream,%00%01%02%03%04

func (*Builder) Close

func (b *Builder) Close() error

Close implements the io.Closer interface. Closing a builder is mandatory to use the URL it built, and may safely be done multiple times.

func (*Builder) PercentEncode

func (b *Builder) PercentEncode()

PercentEncode will result in the URL using an RFC 3986-style percent-encoding scheme (similar to url.PathEscape). If your data is mostly ASCII letters and numbers, this may be more efficient than base64.

Calling PercentEncode after writing anything will panic.

func (*Builder) URL

func (b *Builder) URL() *url.URL

URL returns the encoded representation of all written data. It may be called multiple times, returning a new URL with the same data each time.

If Close has not yet been called, URL will panic.

func (*Builder) Write

func (b *Builder) Write(bs []byte) (int, error)

Write implements the io.Writer interface.

func (*Builder) WriteMediaType

func (b *Builder) WriteMediaType(t string, params map[string]string) error

WriteMediaType writes a RFC 2045-style header before the data in a URL. If no media type is provided RFC 2397 says the content should be considered “text/plain;charset=US-ASCII”; this is unlikely to be the case today even for text so writing an explicit media type is recommended. See also mime.FormatMediaType for general information.

Calling WriteMediaType after writing anything, including calling it twice, will panic.

RFC 2397’s notion of escaping is unfortunately not rigorous; it says to escape values with characters forbidden by RFC 2045 using the method of RFC 2396 (i.e. percent encoding). Here, escaping is instead performed with percent.URIEncoder which escapes many more bytes, following later guidance from RFC 3986. RFC 2045 “tspecials” is not sufficient to avoid confusing URL parsers, including url.Parse. (If you ever find yourself in the position of caring about any of that, I’m sorry.)

type Reader

type Reader struct {
	MediaType       string
	MediaParameters map[string]string
	// contains filtered or unexported fields
}

A Reader reads the data encoded in a data URL.

Example
package main

import (
	"fmt"
	"io"
	"strings"

	"codeberg.org/piman/dataurl"
)

func main() {
	var w strings.Builder
	r, _ := dataurl.NewReader(";base64,QSBicmllZiBub3Rl")
	_, _ = io.Copy(&w, r)
	fmt.Println(r.MediaType)
	fmt.Println(w.String())
}
Output:

text/plain; charset=US-ASCII
A brief note

func NewReader

func NewReader(s string) (*Reader, error)

NewReader returns a Reader for a data URL (without the scheme, i.e. the url.URL.Opaque field).

Some invalid URLs may not be detected until reading.

func (*Reader) Read

func (r *Reader) Read(bs []byte) (int, error)

Read implements the io.Reader interface.

func (*Reader) Size

func (r *Reader) Size() int64

Size returns the total length of the underlying data. The result is unaffected by Read calls.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL