GithubHelp home page GithubHelp logo

shakhmetov / libcno Goto Github PK

View Code? Open in Web Editor NEW

This project forked from pyos/libcno

0.0 0.0 0.0 846 KB

There can never be enough http (2) libraries.

License: MIT License

C 77.64% Python 21.64% Makefile 0.72%

libcno's Introduction

What.

Socketless HTTP 2.

Why.

Mostly because libuv, and therefore libh2o, tends to segfault a lot when used from Python. Also, because why not?

C API

make obj/libcno.a

Just read core.h. And common.h, for buffers and error handling. And hpack.h for headers. Basically, you create a cno_connection_t, then follow a simple chain of cno_init -> connect some callbacks -> cno_begin -> cno_consume -> (repeat while I/O is still possible) -> cno_eof -> cno_fini, skipping to the last step if anything returns an error and using cno_write_head + cno_write_data or cno_write_push or cno_write_reset to send some stuff of your own.

Python API

pip3 install cffi
pip3 install git+https://github.com/pyos/libcno
C constant Python constant
CNO_CLIENT cno.raw.CNO_CLIENT
etc. ...

cno.raw.Connection is an almost complete 1:1 mapping to C API functions.

C function cno.raw.Connection method
cno_init(c, CNO_SERVER) c = cno.raw.Connection(server=True)
cno_fini(c) del c
cno_begin(c, CNO_HTTP2) c.connection_made(is_http2=True)
cno_eof(c) c.connection_lost()
cno_consume(c, data, length) c.data_received(data)
cno_next_stream(c) c.next_stream
cno_write_head(c, stream, msg, final) c.write_head(stream, code, method, path, headers, final)
cno_write_push(c, stream, msg) c.write_push(stream, method, path, headers)
cno_write_data(c, stream, data, length, final) c.write_data(stream, data, final)
cno_write_reset(c, stream, code) c.write_reset(stream, code)

Event receivers must be defined as methods of Connection subclasses.

C event cno.raw.Connection method
on_writev(iov, iovcnt) def on_writev(self, chunks)
on_stream_start(stream) def on_stream_start(self, stream)
on_stream_end(stream, code, side) def on_stream_end(self, stream, code, side)
on_flow_increase(stream) def on_flow_increase(self, stream)
on_message_head(stream, msg) def on_message_head(self, stream, code, method, path, headers)
on_message_tail(stream, msg) def on_message_tail(self, stream, trailers)
on_message_data(stream, data, length) def on_message_data(self, stream, data)
on_message_push(stream, msg, parent) def on_message_push(self, stream, parent, method, path, headers)

On Python 3.5+, higher-level asyncio bindings are also available. Server:

async def handle(request: cno.Request):
    request.method   # :: str
    request.path     # :: str
    request.headers  # :: [(str, str)]
    request.conn     # :: cno.Server -- `protocol` (below)
    request.payload  # :: asyncio.StreamReader

    # Pushed resources inherit :authority and :scheme from the request unless overriden.
    request.push('GET', '/index.css', [('x-extra-header', 'value')])

    if all_data_is_available:
        await request.respond(200, [('content-length', '4')], b'!!!\n')
    else:
        # `Channel` is a subclass of `asyncio.Queue`.
        channel = cno.Channel(max_buffered_chunks, loop=request.conn.loop)
        await channel.put(b'!!!')  # this should preferably be done in a separate
        await channel.put(b'\n')   # coroutine, naturally.
        channel.close()
        # Or you can use any async iterable instead.
        await request.respond(200, [], channel)

make_protocol = lambda: cno.Server(event_loop, handle)
# When using TLS, don't forget to tell clients you support HTTP 2:
# ssl_context.set_alpn_protocols(['h2', 'http/1.1'])
# ssl_context.set_npn_protocols(['h2', 'http/1.1'])
# server = await event_loop.create_server(make_protocol, '', 8000, ssl=ssl_context)

Client:

client = await cno.connect(event_loop, 'https://example.com/')
client.loop       # :: asyncio.BaseEventLoop -- `event_loop`
client.transport  # :: asyncio.Transport
client.is_http2   # :: bool
client.scheme     # :: str  -- https
client.authority  # :: str  -- example.com

response = await client.request('GET', '/', [('user-agent', 'libcno/0.1')])  # cno.Response
response.code     # :: int
response.headers  # :: [(str, str)]
response.payload  # :: asyncio.StreamReader
async for push in response.pushed:
    push.method   # :: str
    push.path     # :: str
    push.headers  # :: [(str, str)]
    await push.response  # :: cno.Response
    # or push.cancel()

response = await client.request('POST', '/whatever', [], b'payload')
# `request`, like `respond`, also accepts `cno.Channel`s as payload.

client.close()

# `cno.connect` automatically sets up a default SSL context and creates
# a TCP connection. To simply create an `asyncio.Protocol`:
client = cno.Client(event_loop, authority='example.com', scheme='https')

# A shorthand for `cno.connect` followed by `client.request`:
response = await cno.request(event_loop, 'GET', 'https://example.com/path', ...)
response.conn.close()

libcno's People

Contributors

pyos 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.