summaryrefslogtreecommitdiff
path: root/libgo/go/http/spdy/protocol.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/http/spdy/protocol.go')
-rw-r--r--libgo/go/http/spdy/protocol.go367
1 files changed, 0 insertions, 367 deletions
diff --git a/libgo/go/http/spdy/protocol.go b/libgo/go/http/spdy/protocol.go
deleted file mode 100644
index d584ea232ea..00000000000
--- a/libgo/go/http/spdy/protocol.go
+++ /dev/null
@@ -1,367 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package spdy is an incomplete implementation of the SPDY protocol.
-//
-// The implementation follows draft 2 of the spec:
-// https://sites.google.com/a/chromium.org/dev/spdy/spdy-protocol/spdy-protocol-draft2
-package spdy
-
-import (
- "bytes"
- "compress/zlib"
- "encoding/binary"
- "http"
- "io"
- "os"
- "strconv"
- "strings"
- "sync"
-)
-
-// Version is the protocol version number that this package implements.
-const Version = 2
-
-// ControlFrameType stores the type field in a control frame header.
-type ControlFrameType uint16
-
-// Control frame type constants
-const (
- TypeSynStream ControlFrameType = 0x0001
- TypeSynReply = 0x0002
- TypeRstStream = 0x0003
- TypeSettings = 0x0004
- TypeNoop = 0x0005
- TypePing = 0x0006
- TypeGoaway = 0x0007
- TypeHeaders = 0x0008
- TypeWindowUpdate = 0x0009
-)
-
-func (t ControlFrameType) String() string {
- switch t {
- case TypeSynStream:
- return "SYN_STREAM"
- case TypeSynReply:
- return "SYN_REPLY"
- case TypeRstStream:
- return "RST_STREAM"
- case TypeSettings:
- return "SETTINGS"
- case TypeNoop:
- return "NOOP"
- case TypePing:
- return "PING"
- case TypeGoaway:
- return "GOAWAY"
- case TypeHeaders:
- return "HEADERS"
- case TypeWindowUpdate:
- return "WINDOW_UPDATE"
- }
- return "Type(" + strconv.Itoa(int(t)) + ")"
-}
-
-type FrameFlags uint8
-
-// Stream frame flags
-const (
- FlagFin FrameFlags = 0x01
- FlagUnidirectional = 0x02
-)
-
-// SETTINGS frame flags
-const (
- FlagClearPreviouslyPersistedSettings FrameFlags = 0x01
-)
-
-// MaxDataLength is the maximum number of bytes that can be stored in one frame.
-const MaxDataLength = 1<<24 - 1
-
-// A Frame is a framed message as sent between clients and servers.
-// There are two types of frames: control frames and data frames.
-type Frame struct {
- Header [4]byte
- Flags FrameFlags
- Data []byte
-}
-
-// ControlFrame creates a control frame with the given information.
-func ControlFrame(t ControlFrameType, f FrameFlags, data []byte) Frame {
- return Frame{
- Header: [4]byte{
- (Version&0xff00)>>8 | 0x80,
- (Version & 0x00ff),
- byte((t & 0xff00) >> 8),
- byte((t & 0x00ff) >> 0),
- },
- Flags: f,
- Data: data,
- }
-}
-
-// DataFrame creates a data frame with the given information.
-func DataFrame(streamId uint32, f FrameFlags, data []byte) Frame {
- return Frame{
- Header: [4]byte{
- byte(streamId & 0x7f000000 >> 24),
- byte(streamId & 0x00ff0000 >> 16),
- byte(streamId & 0x0000ff00 >> 8),
- byte(streamId & 0x000000ff >> 0),
- },
- Flags: f,
- Data: data,
- }
-}
-
-// ReadFrame reads an entire frame into memory.
-func ReadFrame(r io.Reader) (f Frame, err os.Error) {
- _, err = io.ReadFull(r, f.Header[:])
- if err != nil {
- return
- }
- err = binary.Read(r, binary.BigEndian, &f.Flags)
- if err != nil {
- return
- }
- var lengthField [3]byte
- _, err = io.ReadFull(r, lengthField[:])
- if err != nil {
- if err == os.EOF {
- err = io.ErrUnexpectedEOF
- }
- return
- }
- var length uint32
- length |= uint32(lengthField[0]) << 16
- length |= uint32(lengthField[1]) << 8
- length |= uint32(lengthField[2]) << 0
- if length > 0 {
- f.Data = make([]byte, int(length))
- _, err = io.ReadFull(r, f.Data)
- if err == os.EOF {
- err = io.ErrUnexpectedEOF
- }
- } else {
- f.Data = []byte{}
- }
- return
-}
-
-// IsControl returns whether the frame holds a control frame.
-func (f Frame) IsControl() bool {
- return f.Header[0]&0x80 != 0
-}
-
-// Type obtains the type field if the frame is a control frame, otherwise it returns zero.
-func (f Frame) Type() ControlFrameType {
- if !f.IsControl() {
- return 0
- }
- return (ControlFrameType(f.Header[2])<<8 | ControlFrameType(f.Header[3]))
-}
-
-// StreamId returns the stream ID field if the frame is a data frame, otherwise it returns zero.
-func (f Frame) StreamId() (id uint32) {
- if f.IsControl() {
- return 0
- }
- id |= uint32(f.Header[0]) << 24
- id |= uint32(f.Header[1]) << 16
- id |= uint32(f.Header[2]) << 8
- id |= uint32(f.Header[3]) << 0
- return
-}
-
-// WriteTo writes the frame in the SPDY format.
-func (f Frame) WriteTo(w io.Writer) (n int64, err os.Error) {
- var nn int
- // Header
- nn, err = w.Write(f.Header[:])
- n += int64(nn)
- if err != nil {
- return
- }
- // Flags
- nn, err = w.Write([]byte{byte(f.Flags)})
- n += int64(nn)
- if err != nil {
- return
- }
- // Length
- nn, err = w.Write([]byte{
- byte(len(f.Data) & 0x00ff0000 >> 16),
- byte(len(f.Data) & 0x0000ff00 >> 8),
- byte(len(f.Data) & 0x000000ff),
- })
- n += int64(nn)
- if err != nil {
- return
- }
- // Data
- if len(f.Data) > 0 {
- nn, err = w.Write(f.Data)
- n += int64(nn)
- }
- return
-}
-
-// headerDictionary is the dictionary sent to the zlib compressor/decompressor.
-// Even though the specification states there is no null byte at the end, Chrome sends it.
-const headerDictionary = "optionsgetheadpostputdeletetrace" +
- "acceptaccept-charsetaccept-encodingaccept-languageauthorizationexpectfromhost" +
- "if-modified-sinceif-matchif-none-matchif-rangeif-unmodifiedsince" +
- "max-forwardsproxy-authorizationrangerefererteuser-agent" +
- "100101200201202203204205206300301302303304305306307400401402403404405406407408409410411412413414415416417500501502503504505" +
- "accept-rangesageetaglocationproxy-authenticatepublicretry-after" +
- "servervarywarningwww-authenticateallowcontent-basecontent-encodingcache-control" +
- "connectiondatetrailertransfer-encodingupgradeviawarning" +
- "content-languagecontent-lengthcontent-locationcontent-md5content-rangecontent-typeetagexpireslast-modifiedset-cookie" +
- "MondayTuesdayWednesdayThursdayFridaySaturdaySunday" +
- "JanFebMarAprMayJunJulAugSepOctNovDec" +
- "chunkedtext/htmlimage/pngimage/jpgimage/gifapplication/xmlapplication/xhtmltext/plainpublicmax-age" +
- "charset=iso-8859-1utf-8gzipdeflateHTTP/1.1statusversionurl\x00"
-
-// hrSource is a reader that passes through reads from another reader.
-// When the underlying reader reaches EOF, Read will block until another reader is added via change.
-type hrSource struct {
- r io.Reader
- m sync.RWMutex
- c *sync.Cond
-}
-
-func (src *hrSource) Read(p []byte) (n int, err os.Error) {
- src.m.RLock()
- for src.r == nil {
- src.c.Wait()
- }
- n, err = src.r.Read(p)
- src.m.RUnlock()
- if err == os.EOF {
- src.change(nil)
- err = nil
- }
- return
-}
-
-func (src *hrSource) change(r io.Reader) {
- src.m.Lock()
- defer src.m.Unlock()
- src.r = r
- src.c.Broadcast()
-}
-
-// A HeaderReader reads zlib-compressed headers.
-type HeaderReader struct {
- source hrSource
- decompressor io.ReadCloser
-}
-
-// NewHeaderReader creates a HeaderReader with the initial dictionary.
-func NewHeaderReader() (hr *HeaderReader) {
- hr = new(HeaderReader)
- hr.source.c = sync.NewCond(hr.source.m.RLocker())
- return
-}
-
-// ReadHeader reads a set of headers from a reader.
-func (hr *HeaderReader) ReadHeader(r io.Reader) (h http.Header, err os.Error) {
- hr.source.change(r)
- h, err = hr.read()
- return
-}
-
-// Decode reads a set of headers from a block of bytes.
-func (hr *HeaderReader) Decode(data []byte) (h http.Header, err os.Error) {
- hr.source.change(bytes.NewBuffer(data))
- h, err = hr.read()
- return
-}
-
-func (hr *HeaderReader) read() (h http.Header, err os.Error) {
- var count uint16
- if hr.decompressor == nil {
- hr.decompressor, err = zlib.NewReaderDict(&hr.source, []byte(headerDictionary))
- if err != nil {
- return
- }
- }
- err = binary.Read(hr.decompressor, binary.BigEndian, &count)
- if err != nil {
- return
- }
- h = make(http.Header, int(count))
- for i := 0; i < int(count); i++ {
- var name, value string
- name, err = readHeaderString(hr.decompressor)
- if err != nil {
- return
- }
- value, err = readHeaderString(hr.decompressor)
- if err != nil {
- return
- }
- valueList := strings.Split(string(value), "\x00", -1)
- for _, v := range valueList {
- h.Add(name, v)
- }
- }
- return
-}
-
-func readHeaderString(r io.Reader) (s string, err os.Error) {
- var length uint16
- err = binary.Read(r, binary.BigEndian, &length)
- if err != nil {
- return
- }
- data := make([]byte, int(length))
- _, err = io.ReadFull(r, data)
- if err != nil {
- return
- }
- return string(data), nil
-}
-
-// HeaderWriter will write zlib-compressed headers on different streams.
-type HeaderWriter struct {
- compressor *zlib.Writer
- buffer *bytes.Buffer
-}
-
-// NewHeaderWriter creates a HeaderWriter ready to compress headers.
-func NewHeaderWriter(level int) (hw *HeaderWriter) {
- hw = &HeaderWriter{buffer: new(bytes.Buffer)}
- hw.compressor, _ = zlib.NewWriterDict(hw.buffer, level, []byte(headerDictionary))
- return
-}
-
-// WriteHeader writes a header block directly to an output.
-func (hw *HeaderWriter) WriteHeader(w io.Writer, h http.Header) (err os.Error) {
- hw.write(h)
- _, err = io.Copy(w, hw.buffer)
- hw.buffer.Reset()
- return
-}
-
-// Encode returns a compressed header block.
-func (hw *HeaderWriter) Encode(h http.Header) (data []byte) {
- hw.write(h)
- data = make([]byte, hw.buffer.Len())
- hw.buffer.Read(data)
- return
-}
-
-func (hw *HeaderWriter) write(h http.Header) {
- binary.Write(hw.compressor, binary.BigEndian, uint16(len(h)))
- for k, vals := range h {
- k = strings.ToLower(k)
- binary.Write(hw.compressor, binary.BigEndian, uint16(len(k)))
- binary.Write(hw.compressor, binary.BigEndian, []byte(k))
- v := strings.Join(vals, "\x00")
- binary.Write(hw.compressor, binary.BigEndian, uint16(len(v)))
- binary.Write(hw.compressor, binary.BigEndian, []byte(v))
- }
- hw.compressor.Flush()
-}