GithubHelp home page GithubHelp logo

http2.jl's Introduction

HTTP2

Build Status HTTPClient

A HTTP2 support library that handles frames, streams and connections.

julia> Pkg.add("HTTP2")
julia> using HTTP2

Simple Servers and Clients

The library can directly create simple servers and clients. For full support of HTTP/2 Upgrade and HTTPS, use HttpServer.jl and Requests.jl.

You only use this library directly if you need low-level functionality. An example for the server is as follows. The code will be explained in the next section.

server = listen(port)

println("Server started.")
while(true)
    buffer = accept(server)
    println("Processing a connection ...")

    connection = Session.new_connection(buffer; isclient=false)
    ## Recv the client preface, and send an empty SETTING frame.

    headers_evt = Session.take_evt!(connection)
    stream_identifier = headers_evt.stream_identifier

    sending_headers = Headers(":status" => "200",
                              "server" => "HTTP2.jl",
                              "date" => Dates.format(now(Dates.UTC), Dates.RFC1123Format),
                              "content-type" => "text/html; charset=UTF-8")

    Session.put_act!(connection, Session.ActSendHeaders(stream_identifier, sending_headers, false))
    Session.put_act!(connection, Session.ActSendData(stream_identifier, body, true))

    ## We are done!
end

A client can be started in a similar way. Again the code will be explained in the next section.

buffer = connect(dest, port)

## Create a HTTPConnection object
connection = Session.new_connection(buffer; isclient=true)

## Create a request with headers
headers = Headers(":method" => "GET",
                  ":path" => url,
                  ":scheme" => "http",
                  ":authority" => "127.0.0.1:9000",
                  "accept" => "*/*",
                  "accept-encoding" => "gzip, deflate",
                  "user-agent" => "HTTP2.jl")

Session.put_act!(connection, Session.ActSendHeaders(Session.next_free_stream_identifier(connection), headers, true))

return (Session.take_evt!(connection).headers, Session.take_evt!(connection).data)

Connection Lifecycle

HTTP/2 is a binary protocol, and can handle multiple requests and responses in one connection. As a result, you cannot read and write directly in the stream like HTTP/1.1. Instead, you talk with the connection through channels. The main interface of low-level HTTP/2 support resides in HTTP2.Session module.

import HTTP2.Session

Create a Buffer

First you need to create a buffer that the connection can read and write. A normal TCP connection from a client is usually like this:

buffer = connect(dest, port)

While for server, it usually looks like this:

server = listen(port)
buffer = accept(server)

You can also use MbedTLS.jl or other TLS library to get a buffer over TLS and initialize a HTTPS connection.

Initialize the Connection

After getting the buffer, we can start to initialize the connection.

connection = Session.new_connection(buffer; isclient=true)

isclient key indicates whether you are a server or a client. This is needed because the server and client uses different stream identifiers.

Another important key to note is skip_preface. For a normal HTTP/2 connection, this is usually set to false. However, if you are doing HTTP/2 protocol upgrade (in which case the HTTP/2 preface should be skipped), you should set this key to true.

Initialize a New Stream

You don't need to do anything in particular to initialize a new stream, because they are solely identified by its identifier. To get a new stream identifier, call the next_free_stream_identifier(connection) function.

Send and Receive Headers and Data

The connection is then alive, and you can start to send or receive headers and data through the connection. Those are done by the take_evt! and put_act! functions. take_evt!(connection) waits and return an event struct from the connection. put_act!(connection, action) put a new action to the connection and returns immediately.

Actions

  • ActPromise(stream_identifier, promised_stream_identifier, headers): This is usually sent from a server which sends a push promise. stream_identifier is the main stream identifier, promised_stream_identifier is the promised stream identifier that is going to be pushed, and headers are a Headers struct that sends the requests.
  • ActSendHeaders(stream_identifier, headers, is_end_stream): This can be used to send request headers, response headers, or other headers specified in the HTTP specification. If there's no more headers or data to be sent in the stream, is_end_stream should set to true.
  • ActSendData(stream_identifier, data, is_end_stream): This can be used to send request body, response body, or if a protocol switch is initialized, other specified protocol data. If there's no more headers or data to be sent in the stream, is_end_stream should set to true.

Events

  • EvtPromise(stream_identifier, promised_stream_identifier, headers): This event is triggered when a push promise is received. The struct is similar to ActPromise.
  • EvtRecvHeaders(stream_identifier, headers, is_end_stream): This event is triggered when a header is received. The struct is similar to ActSendHeaders.
  • EvtRecvData(stream_identifier, data, is_end_stream): This event is triggered when data is received in a stream. The struct is similar to ActSendData.
  • EvtGoaway(): This event is triggered when the whole connection is about to be closed.

Close the Connection

The connection can be closed using close(connection).

Frame

You can do using HTTP2.Frame to import the library. After that, a encode function and a decode function are available. The encode function takes a typed frame into its binary form. The decode function takes an IO buffer, and returns a typed frame.

For details about frames, see the HTTP2 Specification.

http2.jl's People

Contributors

sorpaas avatar staticfloat avatar tanmaykm avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.