Add protocol property to the transport
Transport should be protocol aware because it should be possible to switch the protocol if the operation is supported, for example for upgrading HTTP to web sockets or HTTP 1.1 to HTTP/2.
This commit is contained in:
parent
43c28b749d
commit
48a49c2a2d
@ -3,7 +3,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Copyright: Eugene Wissner 2016.
|
||||
* Copyright: Eugene Wissner 2016-2017.
|
||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||
* Mozilla Public License, v. 2.0).
|
||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||
|
@ -3,7 +3,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Copyright: Eugene Wissner 2016.
|
||||
* Copyright: Eugene Wissner 2016-2017.
|
||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||
* Mozilla Public License, v. 2.0).
|
||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||
@ -13,6 +13,7 @@ module tanya.async.event.selector;
|
||||
version (Posix):
|
||||
|
||||
import tanya.async.loop;
|
||||
import tanya.async.protocol;
|
||||
import tanya.async.transport;
|
||||
import tanya.async.watcher;
|
||||
import tanya.container.buffer;
|
||||
@ -28,6 +29,8 @@ class SelectorStreamTransport : StreamTransport
|
||||
{
|
||||
private ConnectedSocket socket_;
|
||||
|
||||
private Protocol protocol_;
|
||||
|
||||
/// Input buffer.
|
||||
package WriteBuffer!ubyte input;
|
||||
|
||||
@ -40,22 +43,64 @@ class SelectorStreamTransport : StreamTransport
|
||||
* Params:
|
||||
* loop = Event loop.
|
||||
* socket = Socket.
|
||||
* protocol = Application protocol.
|
||||
*
|
||||
* Precondition: $(D_INLINECODE loop !is null
|
||||
* && socket !is null
|
||||
* && protocol !is null)
|
||||
*/
|
||||
this(SelectorLoop loop, ConnectedSocket socket) @nogc
|
||||
this(SelectorLoop loop, ConnectedSocket socket, Protocol protocol) @nogc
|
||||
in
|
||||
{
|
||||
assert(loop !is null);
|
||||
assert(socket !is null);
|
||||
assert(protocol !is null);
|
||||
}
|
||||
body
|
||||
{
|
||||
socket_ = socket;
|
||||
this.loop = loop;
|
||||
protocol_ = protocol;
|
||||
input = WriteBuffer!ubyte(8192, MmapPool.instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns: Transport socket.
|
||||
*/
|
||||
inout(ConnectedSocket) socket() inout pure nothrow @safe @nogc
|
||||
ConnectedSocket socket() pure nothrow @safe @nogc
|
||||
{
|
||||
return socket_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns: Application protocol.
|
||||
*/
|
||||
@property Protocol protocol() pure nothrow @safe @nogc
|
||||
{
|
||||
return protocol_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches the protocol.
|
||||
*
|
||||
* The protocol is deallocated by the event loop, it should currently be
|
||||
* allocated with $(D_PSYMBOL MmapPool).
|
||||
*
|
||||
* Params:
|
||||
* protocol = Application protocol.
|
||||
*
|
||||
* Precondition: $(D_INLINECODE protocol !is null)
|
||||
*/
|
||||
@property void protocol(Protocol protocol) pure nothrow @safe @nogc
|
||||
in
|
||||
{
|
||||
assert(protocol !is null);
|
||||
}
|
||||
body
|
||||
{
|
||||
protocol_ = protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write some data to the transport.
|
||||
*
|
||||
@ -224,7 +269,8 @@ abstract class SelectorLoop : Loop
|
||||
}
|
||||
|
||||
IOWatcher io;
|
||||
auto transport = MmapPool.instance.make!SelectorStreamTransport(this, client);
|
||||
auto protocol = connection.protocol;
|
||||
auto transport = MmapPool.instance.make!SelectorStreamTransport(this, client, protocol);
|
||||
|
||||
if (connections.length > client.handle)
|
||||
{
|
||||
@ -236,13 +282,12 @@ abstract class SelectorLoop : Loop
|
||||
}
|
||||
if (io is null)
|
||||
{
|
||||
io = MmapPool.instance.make!IOWatcher(transport,
|
||||
connection.protocol);
|
||||
io = MmapPool.instance.make!IOWatcher(transport, protocol);
|
||||
connections[client.handle] = io;
|
||||
}
|
||||
else
|
||||
{
|
||||
io(transport, connection.protocol);
|
||||
io(transport, protocol);
|
||||
}
|
||||
|
||||
reify(io, EventMask(Event.none), EventMask(Event.read, Event.write));
|
||||
|
@ -3,7 +3,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Copyright: Eugene Wissner 2016.
|
||||
* Copyright: Eugene Wissner 2016-2017.
|
||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||
* Mozilla Public License, v. 2.0).
|
||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||
|
@ -3,7 +3,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Copyright: Eugene Wissner 2016.
|
||||
* Copyright: Eugene Wissner 2016-2017.
|
||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||
* Mozilla Public License, v. 2.0).
|
||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||
|
@ -3,13 +3,14 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Copyright: Eugene Wissner 2016.
|
||||
* Copyright: Eugene Wissner 2016-2017.
|
||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||
* Mozilla Public License, v. 2.0).
|
||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||
*/
|
||||
module tanya.async.transport;
|
||||
|
||||
import tanya.async.protocol;
|
||||
import tanya.network.socket;
|
||||
|
||||
/**
|
||||
@ -45,6 +46,33 @@ interface WriteTransport : Transport
|
||||
*/
|
||||
interface DuplexTransport : ReadTransport, WriteTransport
|
||||
{
|
||||
/**
|
||||
* Returns: Application protocol.
|
||||
*
|
||||
* Postcondition: $(D_INLINECODE protocol !is null)
|
||||
*/
|
||||
@property Protocol protocol() pure nothrow @safe @nogc
|
||||
out (protocol)
|
||||
{
|
||||
assert(protocol !is null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches the protocol.
|
||||
*
|
||||
* The protocol is deallocated by the event loop, it should currently be
|
||||
* allocated with $(D_PSYMBOL MmapPool).
|
||||
*
|
||||
* Params:
|
||||
* protocol = Application protocol.
|
||||
*
|
||||
* Precondition: $(D_INLINECODE protocol !is null)
|
||||
*/
|
||||
@property void protocol(Protocol protocol) pure nothrow @safe @nogc
|
||||
in
|
||||
{
|
||||
assert(protocol !is null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -52,7 +80,7 @@ interface DuplexTransport : ReadTransport, WriteTransport
|
||||
*/
|
||||
interface SocketTransport : Transport
|
||||
{
|
||||
@property inout(Socket) socket() inout pure nothrow @safe @nogc;
|
||||
@property Socket socket() pure nothrow @safe @nogc;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,7 +3,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Copyright: Eugene Wissner 2016.
|
||||
* Copyright: Eugene Wissner 2016-2017.
|
||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||
* Mozilla Public License, v. 2.0).
|
||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||
@ -90,7 +90,7 @@ class ConnectionWatcher : Watcher
|
||||
/**
|
||||
* Returns: Socket.
|
||||
*/
|
||||
@property inout(Socket) socket() inout pure nothrow @nogc
|
||||
@property Socket socket() pure nothrow @nogc
|
||||
{
|
||||
return socket_;
|
||||
}
|
||||
@ -222,7 +222,7 @@ class IOWatcher : ConnectionWatcher
|
||||
/**
|
||||
* Returns: Socket.
|
||||
*/
|
||||
override @property inout(Socket) socket() inout pure nothrow @nogc
|
||||
override @property Socket socket() pure nothrow @nogc
|
||||
{
|
||||
return transport.socket;
|
||||
}
|
||||
|
77
source/tanya/container/string.d
Normal file
77
source/tanya/container/string.d
Normal file
@ -0,0 +1,77 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Copyright: Eugene Wissner 2016-2017.
|
||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||
* Mozilla Public License, v. 2.0).
|
||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||
*/
|
||||
module tanya.container.string;
|
||||
|
||||
import core.exception;
|
||||
import core.stdc.string;
|
||||
import tanya.memory;
|
||||
|
||||
/**
|
||||
* UTF-8 string.
|
||||
*/
|
||||
struct String
|
||||
{
|
||||
private char[] data;
|
||||
private size_t length_;
|
||||
|
||||
invariant
|
||||
{
|
||||
assert(length_ <= data.length);
|
||||
}
|
||||
|
||||
/// Ditto.
|
||||
this(const(char)[] str, shared Allocator allocator = defaultAllocator)
|
||||
nothrow @trusted @nogc
|
||||
{
|
||||
this(allocator);
|
||||
|
||||
data = cast(char[]) allocator.allocate(str.length);
|
||||
if (str.length > 0 && data is null)
|
||||
{
|
||||
onOutOfMemoryErrorNoGC();
|
||||
}
|
||||
memcpy(data.ptr, str.ptr, str.length);
|
||||
}
|
||||
|
||||
/// Ditto.
|
||||
this(const(wchar)[] str, shared Allocator allocator = defaultAllocator)
|
||||
nothrow @trusted @nogc
|
||||
{
|
||||
this(allocator);
|
||||
|
||||
}
|
||||
|
||||
/// Ditto.
|
||||
this(const(dchar)[] str, shared Allocator allocator = defaultAllocator)
|
||||
nothrow @trusted @nogc
|
||||
{
|
||||
this(allocator);
|
||||
|
||||
}
|
||||
|
||||
/// Ditto.
|
||||
this(shared Allocator allocator) pure nothrow @safe @nogc
|
||||
in
|
||||
{
|
||||
assert(allocator !is null);
|
||||
}
|
||||
body
|
||||
{
|
||||
allocator_ = allocator;
|
||||
}
|
||||
|
||||
~this() nothrow @trusted @nogc
|
||||
{
|
||||
allocator.deallocate(data);
|
||||
}
|
||||
|
||||
mixin DefaultAllocator;
|
||||
}
|
Loading…
Reference in New Issue
Block a user