mirror of
https://github.com/markqvist/Reticulum.git
synced 2024-12-24 23:19:36 -05:00
Implemented request and response API
This commit is contained in:
parent
69930e5652
commit
1dc6655017
283
Examples/Request.py
Normal file
283
Examples/Request.py
Normal file
@ -0,0 +1,283 @@
|
||||
##########################################################
|
||||
# This RNS example demonstrates how to set perform #
|
||||
# requests and receive responses over a link. #
|
||||
##########################################################
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import random
|
||||
import argparse
|
||||
import RNS
|
||||
|
||||
# Let's define an app name. We'll use this for all
|
||||
# destinations we create. Since this echo example
|
||||
# is part of a range of example utilities, we'll put
|
||||
# them all within the app namespace "example_utilities"
|
||||
APP_NAME = "example_utilities"
|
||||
|
||||
##########################################################
|
||||
#### Server Part #########################################
|
||||
##########################################################
|
||||
|
||||
# A reference to the latest client link that connected
|
||||
latest_client_link = None
|
||||
|
||||
def random_text_generator(path, data, request_id, remote_identity_hash, requested_at):
|
||||
RNS.log("Generating response to request "+RNS.prettyhexrep(request_id))
|
||||
texts = ["They looked up", "On each full moon", "Becky was upset", "I’ll stay away from it", "The pet shop stocks everything"]
|
||||
return texts[random.randint(0, len(texts)-1)]
|
||||
|
||||
# This initialisation is executed when the users chooses
|
||||
# to run as a server
|
||||
def server(configpath):
|
||||
# We must first initialise Reticulum
|
||||
reticulum = RNS.Reticulum(configpath)
|
||||
|
||||
# Randomly create a new identity for our link example
|
||||
server_identity = RNS.Identity()
|
||||
|
||||
# We create a destination that clients can connect to. We
|
||||
# want clients to create links to this destination, so we
|
||||
# need to create a "single" destination type.
|
||||
server_destination = RNS.Destination(
|
||||
server_identity,
|
||||
RNS.Destination.IN,
|
||||
RNS.Destination.SINGLE,
|
||||
APP_NAME,
|
||||
"requestexample"
|
||||
)
|
||||
|
||||
# We configure a function that will get called every time
|
||||
# a new client creates a link to this destination.
|
||||
server_destination.set_link_established_callback(client_connected)
|
||||
|
||||
# We register a request handler for handling incoming
|
||||
# requests over any established links.
|
||||
server_destination.register_request_handler(
|
||||
"/random/text",
|
||||
response_generator = random_text_generator,
|
||||
allow = RNS.Destination.ALLOW_ALL
|
||||
)
|
||||
|
||||
# Everything's ready!
|
||||
# Let's Wait for client requests or user input
|
||||
server_loop(server_destination)
|
||||
|
||||
def server_loop(destination):
|
||||
# Let the user know that everything is ready
|
||||
RNS.log(
|
||||
"Request example "+
|
||||
RNS.prettyhexrep(destination.hash)+
|
||||
" running, waiting for a connection."
|
||||
)
|
||||
|
||||
RNS.log("Hit enter to manually send an announce (Ctrl-C to quit)")
|
||||
|
||||
# We enter a loop that runs until the users exits.
|
||||
# If the user hits enter, we will announce our server
|
||||
# destination on the network, which will let clients
|
||||
# know how to create messages directed towards it.
|
||||
while True:
|
||||
entered = input()
|
||||
destination.announce()
|
||||
RNS.log("Sent announce from "+RNS.prettyhexrep(destination.hash))
|
||||
|
||||
# When a client establishes a link to our server
|
||||
# destination, this function will be called with
|
||||
# a reference to the link.
|
||||
def client_connected(link):
|
||||
global latest_client_link
|
||||
|
||||
RNS.log("Client connected")
|
||||
link.set_link_closed_callback(client_disconnected)
|
||||
latest_client_link = link
|
||||
|
||||
def client_disconnected(link):
|
||||
RNS.log("Client disconnected")
|
||||
|
||||
|
||||
##########################################################
|
||||
#### Client Part #########################################
|
||||
##########################################################
|
||||
|
||||
# A reference to the server link
|
||||
server_link = None
|
||||
|
||||
# This initialisation is executed when the users chooses
|
||||
# to run as a client
|
||||
def client(destination_hexhash, configpath):
|
||||
# We need a binary representation of the destination
|
||||
# hash that was entered on the command line
|
||||
try:
|
||||
if len(destination_hexhash) != 20:
|
||||
raise ValueError("Destination length is invalid, must be 20 hexadecimal characters (10 bytes)")
|
||||
destination_hash = bytes.fromhex(destination_hexhash)
|
||||
except:
|
||||
RNS.log("Invalid destination entered. Check your input!\n")
|
||||
exit()
|
||||
|
||||
# We must first initialise Reticulum
|
||||
reticulum = RNS.Reticulum(configpath)
|
||||
|
||||
# Check if we know a path to the destination
|
||||
if not RNS.Transport.has_path(destination_hash):
|
||||
RNS.log("Destination is not yet known. Requesting path and waiting for announce to arrive...")
|
||||
RNS.Transport.request_path(destination_hash)
|
||||
while not RNS.Transport.has_path(destination_hash):
|
||||
time.sleep(0.1)
|
||||
|
||||
# Recall the server identity
|
||||
server_identity = RNS.Identity.recall(destination_hash)
|
||||
|
||||
# Inform the user that we'll begin connecting
|
||||
RNS.log("Establishing link with server...")
|
||||
|
||||
# When the server identity is known, we set
|
||||
# up a destination
|
||||
server_destination = RNS.Destination(
|
||||
server_identity,
|
||||
RNS.Destination.OUT,
|
||||
RNS.Destination.SINGLE,
|
||||
APP_NAME,
|
||||
"requestexample"
|
||||
)
|
||||
|
||||
# And create a link
|
||||
link = RNS.Link(server_destination)
|
||||
|
||||
# We'll set up functions to inform the
|
||||
# user when the link is established or closed
|
||||
link.set_link_established_callback(link_established)
|
||||
link.set_link_closed_callback(link_closed)
|
||||
|
||||
# Everything is set up, so let's enter a loop
|
||||
# for the user to interact with the example
|
||||
client_loop()
|
||||
|
||||
def client_loop():
|
||||
global server_link
|
||||
|
||||
# Wait for the link to become active
|
||||
while not server_link:
|
||||
time.sleep(0.1)
|
||||
|
||||
should_quit = False
|
||||
while not should_quit:
|
||||
try:
|
||||
print("> ", end=" ")
|
||||
text = input()
|
||||
|
||||
# Check if we should quit the example
|
||||
if text == "quit" or text == "q" or text == "exit":
|
||||
should_quit = True
|
||||
server_link.teardown()
|
||||
|
||||
else:
|
||||
server_link.request(
|
||||
"/random/text",
|
||||
data = None,
|
||||
response_callback = got_response,
|
||||
failed_callback = request_failed
|
||||
)
|
||||
|
||||
|
||||
except Exception as e:
|
||||
RNS.log("Error while sending request over the link: "+str(e))
|
||||
should_quit = True
|
||||
server_link.teardown()
|
||||
|
||||
def got_response(request_receipt):
|
||||
request_id = request_receipt.request_id
|
||||
response = request_receipt.response
|
||||
|
||||
RNS.log("Got response for request "+RNS.prettyhexrep(request_id)+": "+str(response))
|
||||
|
||||
def request_received(request_receipt):
|
||||
RNS.log("The request "+RNS.prettyhexrep(request_receipt.request_id)+" was received by the remote peer.")
|
||||
|
||||
def request_failed(request_receipt):
|
||||
RNS.log("The request "+RNS.prettyhexrep(request_receipt.request_id)+" failed.")
|
||||
|
||||
|
||||
# This function is called when a link
|
||||
# has been established with the server
|
||||
def link_established(link):
|
||||
# We store a reference to the link
|
||||
# instance for later use
|
||||
global server_link
|
||||
server_link = link
|
||||
|
||||
# Inform the user that the server is
|
||||
# connected
|
||||
RNS.log("Link established with server, hit enter to perform a request, or type in \"quit\" to quit")
|
||||
|
||||
# When a link is closed, we'll inform the
|
||||
# user, and exit the program
|
||||
def link_closed(link):
|
||||
if link.teardown_reason == RNS.Link.TIMEOUT:
|
||||
RNS.log("The link timed out, exiting now")
|
||||
elif link.teardown_reason == RNS.Link.DESTINATION_CLOSED:
|
||||
RNS.log("The link was closed by the server, exiting now")
|
||||
else:
|
||||
RNS.log("Link closed, exiting now")
|
||||
|
||||
RNS.Reticulum.exit_handler()
|
||||
time.sleep(1.5)
|
||||
os._exit(0)
|
||||
|
||||
|
||||
##########################################################
|
||||
#### Program Startup #####################################
|
||||
##########################################################
|
||||
|
||||
# This part of the program runs at startup,
|
||||
# and parses input of from the user, and then
|
||||
# starts up the desired program mode.
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
parser = argparse.ArgumentParser(description="Simple request/response example")
|
||||
|
||||
parser.add_argument(
|
||||
"-s",
|
||||
"--server",
|
||||
action="store_true",
|
||||
help="wait for incoming requests from clients"
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--config",
|
||||
action="store",
|
||||
default=None,
|
||||
help="path to alternative Reticulum config directory",
|
||||
type=str
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"destination",
|
||||
nargs="?",
|
||||
default=None,
|
||||
help="hexadecimal hash of the server destination",
|
||||
type=str
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.config:
|
||||
configarg = args.config
|
||||
else:
|
||||
configarg = None
|
||||
|
||||
if args.server:
|
||||
server(configarg)
|
||||
else:
|
||||
if (args.destination == None):
|
||||
print("")
|
||||
parser.print_help()
|
||||
print("")
|
||||
else:
|
||||
client(args.destination, configarg)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("")
|
||||
exit()
|
@ -40,6 +40,11 @@ class Destination:
|
||||
PROVE_ALL = 0x23
|
||||
proof_strategies = [PROVE_NONE, PROVE_APP, PROVE_ALL]
|
||||
|
||||
ALLOW_NONE = 0x00
|
||||
ALLOW_ALL = 0x01
|
||||
ALLOW_LIST = 0x02
|
||||
request_policies = [ALLOW_NONE, ALLOW_ALL, ALLOW_LIST]
|
||||
|
||||
IN = 0x11;
|
||||
OUT = 0x12;
|
||||
directions = [IN, OUT]
|
||||
@ -97,6 +102,7 @@ class Destination:
|
||||
if not type in Destination.types: raise ValueError("Unknown destination type")
|
||||
if not direction in Destination.directions: raise ValueError("Unknown destination direction")
|
||||
self.callbacks = Callbacks()
|
||||
self.request_handlers = {}
|
||||
self.type = type
|
||||
self.direction = direction
|
||||
self.proof_strategy = Destination.PROVE_NONE
|
||||
@ -208,6 +214,45 @@ class Destination:
|
||||
else:
|
||||
self.proof_strategy = proof_strategy
|
||||
|
||||
|
||||
def register_request_handler(self, path, response_generator = None, allow = ALLOW_NONE, allowed_list = None):
|
||||
"""
|
||||
Registers a request handler.
|
||||
|
||||
:param path: The path for the request handler to be registered.
|
||||
:param response_generator: A function or method with the signature *response_generator(path, data, request_id, remote_identity_hash, requested_at)* to be called. Whatever this funcion returns will be sent as a response to the requester. If the function returns ``None``, no response will be sent.
|
||||
:param allow: One of ``RNS.Destination.ALLOW_NONE``, ``RNS.Destination.ALLOW_ALL`` or ``RNS.Destination.ALLOW_LIST``. If ``RNS.Destination.ALLOW_LIST`` is set, the request handler will only respond to requests for identified peers in the supplied list.
|
||||
:param allowed_list: A list of *bytes-like* :ref:`RNS.Identity<api-identity>` hashes.
|
||||
:raises: ``ValueError`` if any of the supplied arguments are invalid.
|
||||
"""
|
||||
if path == None or path == "":
|
||||
raise ValueError("Invalid path specified")
|
||||
elif not callable(response_generator):
|
||||
raise ValueError("Invalid response generator specified")
|
||||
elif not allow in Destination.request_policies:
|
||||
raise ValueError("Invalid request policy")
|
||||
else:
|
||||
path_hash = RNS.Identity.truncated_hash(path.encode("utf-8"))
|
||||
request_handler = [path, response_generator, allow, allowed_list]
|
||||
self.request_handlers[path_hash] = request_handler
|
||||
|
||||
|
||||
def deregister_request_handler(self, path):
|
||||
"""
|
||||
Deregisters a request handler.
|
||||
|
||||
:param path: The path for the request handler to be deregistered.
|
||||
:returns: True if the handler was deregistered, otherwise False.
|
||||
"""
|
||||
path_hash = RNS.Identity.truncated_hash(path.encode("utf-8"))
|
||||
if path_hash in self.request_handlers:
|
||||
self.request_handlers.pop(path_hash)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
|
||||
def receive(self, packet):
|
||||
if packet.packet_type == RNS.Packet.LINKREQUEST:
|
||||
plaintext = packet.data
|
||||
|
139
RNS/Link.py
139
RNS/Link.py
@ -110,6 +110,7 @@ class Link:
|
||||
self.resource_strategy = Link.ACCEPT_NONE
|
||||
self.outgoing_resources = []
|
||||
self.incoming_resources = []
|
||||
self.pending_requests = []
|
||||
self.last_inbound = 0
|
||||
self.last_outbound = 0
|
||||
self.tx = 0
|
||||
@ -265,6 +266,26 @@ class Link:
|
||||
self.had_outbound()
|
||||
|
||||
|
||||
def request(self, path, data = None, response_callback = None, failed_callback = None):
|
||||
"""
|
||||
Sends a request to the remote peer.
|
||||
|
||||
:param path: The request path.
|
||||
:param response_callback: A function or method with the signature *response_callback(request_receipt)* to be called when a response is received. See the :ref:`Request Example<example-request>` for more info.
|
||||
:param failed_callback: A function or method with the signature *failed_callback(request_receipt)* to be called when a request fails. See the :ref:`Request Example<example-request>` for more info.
|
||||
"""
|
||||
request_path_hash = RNS.Identity.truncated_hash(path.encode("utf-8"))
|
||||
unpacked_request = [time.time(), request_path_hash, data]
|
||||
packed_request = umsgpack.packb(unpacked_request)
|
||||
|
||||
if len(packed_request) <= Link.MDU:
|
||||
request_packet = RNS.Packet(self, packed_request, RNS.Packet.DATA, context = RNS.Packet.REQUEST)
|
||||
return RequestReceipt(self, request_packet.send(), response_callback, failed_callback)
|
||||
else:
|
||||
# TODO: Implement sending requests as Resources
|
||||
raise IOError("Request size of "+str(len(packed_request))+" exceeds MDU of "+str(Link.MDU)+" bytes")
|
||||
|
||||
|
||||
def rtt_packet(self, packet):
|
||||
try:
|
||||
# TODO: This is crude, we should use the delta
|
||||
@ -467,6 +488,70 @@ class Link:
|
||||
if self.callbacks.remote_identified != None:
|
||||
self.callbacks.remote_identified(self.__remote_identity)
|
||||
|
||||
elif packet.context == RNS.Packet.REQUEST:
|
||||
try:
|
||||
request_id = packet.getTruncatedHash()
|
||||
packed_request = self.decrypt(packet.data)
|
||||
unpacked_request = umsgpack.unpackb(packed_request)
|
||||
requested_at = unpacked_request[0]
|
||||
path_hash = unpacked_request[1]
|
||||
request_data = unpacked_request[2]
|
||||
|
||||
if path_hash in self.destination.request_handlers:
|
||||
request_handler = self.destination.request_handlers[path_hash]
|
||||
path = request_handler[0]
|
||||
response_generator = request_handler[1]
|
||||
allow = request_handler[2]
|
||||
allowed_list = request_handler[3]
|
||||
|
||||
allowed = False
|
||||
if not allow == RNS.Destination.ALLOW_NONE:
|
||||
if allow == RNS.Destination.ALLOW_LIST:
|
||||
if self.__remote_identity in allowed_list:
|
||||
allowed = True
|
||||
elif allow == RNS.Destination.ALLOW_ALL:
|
||||
allowed = True
|
||||
|
||||
if allowed:
|
||||
response = response_generator(path, request_data, request_id, self.__remote_identity, requested_at)
|
||||
if response != None:
|
||||
packed_response = umsgpack.packb([request_id, True, response])
|
||||
|
||||
if len(packed_response) <= Link.MDU:
|
||||
RNS.Packet(self, packed_response, RNS.Packet.DATA, context = RNS.Packet.RESPONSE).send()
|
||||
else:
|
||||
# TODO: Implement transfer as resource
|
||||
packed_response = umsgpack.packb([request_id, False, None])
|
||||
raise Exception("Response transfer as resource not implemented")
|
||||
|
||||
except Exception as e:
|
||||
RNS.log("Error occurred while handling request. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
|
||||
elif packet.context == RNS.Packet.RESPONSE:
|
||||
packed_response = self.decrypt(packet.data)
|
||||
unpacked_response = umsgpack.unpackb(packed_response)
|
||||
request_id = unpacked_response[0]
|
||||
|
||||
if unpacked_response[1] == True:
|
||||
remove = None
|
||||
for pending_request in self.pending_requests:
|
||||
if pending_request.request_id == request_id:
|
||||
response_data = unpacked_response[2]
|
||||
remove = pending_request
|
||||
try:
|
||||
pending_request.response_received(response_data)
|
||||
except Exception as e:
|
||||
RNS.log("Error occurred while handling response. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
|
||||
break
|
||||
|
||||
if remove != None:
|
||||
self.pending_requests.remove(remove)
|
||||
|
||||
else:
|
||||
# TODO: Implement receiving responses as Resources
|
||||
raise Exception("Response transfer as resource not implemented")
|
||||
|
||||
elif packet.context == RNS.Packet.LRRTT:
|
||||
if not self.initiator:
|
||||
self.rtt_packet(packet)
|
||||
@ -692,3 +777,57 @@ class Link:
|
||||
|
||||
def __str__(self):
|
||||
return RNS.prettyhexrep(self.link_id)
|
||||
|
||||
|
||||
class RequestReceipt():
|
||||
FAILED = 0x00
|
||||
SENT = 0x01
|
||||
DELIVERED = 0x02
|
||||
READY = 0x03
|
||||
|
||||
def __init__(self, link, packet_receipt, response_callback = None, failed_callback = None):
|
||||
self.hash = packet_receipt.truncated_hash
|
||||
self.link = link
|
||||
self.request_id = self.hash
|
||||
|
||||
self.response = None
|
||||
self.status = RequestReceipt.SENT
|
||||
self.sent_at = time.time()
|
||||
self.timeout = RNS.Packet.TIMEOUT
|
||||
self.concluded_at = None
|
||||
|
||||
self.callbacks = RequestReceiptCallbacks()
|
||||
self.callbacks.response = response_callback
|
||||
self.callbacks.failed = failed_callback
|
||||
|
||||
self.packet_receipt = packet_receipt
|
||||
self.packet_receipt.set_timeout_callback(self.request_timed_out)
|
||||
|
||||
self.link.pending_requests.append(self)
|
||||
|
||||
|
||||
def request_timed_out(self, packet_receipt):
|
||||
self.status = RequestReceipt.FAILED
|
||||
self.concluded_at = time.time()
|
||||
self.link.pending_requests.remove(self)
|
||||
|
||||
if self.callbacks.failed != None:
|
||||
self.callbacks.failed(self)
|
||||
|
||||
def response_received(self, response):
|
||||
self.response = response
|
||||
|
||||
self.packet_receipt.status = RNS.PacketReceipt.DELIVERED
|
||||
self.packet_receipt.proved = True
|
||||
self.packet_receipt.concluded_at = time.time()
|
||||
if self.packet_receipt.callbacks.delivery != None:
|
||||
self.packet_receipt.callbacks.delivery(self)
|
||||
|
||||
if self.callbacks.response != None:
|
||||
self.callbacks.response(self)
|
||||
|
||||
|
||||
class RequestReceiptCallbacks:
|
||||
def __init__(self):
|
||||
self.response = None
|
||||
self.failed = None
|
@ -41,7 +41,7 @@ class Packet:
|
||||
HEADER_4 = 0x03 # Reserved
|
||||
header_types = [HEADER_1, HEADER_2, HEADER_3, HEADER_4]
|
||||
|
||||
# Data packet context types
|
||||
# Packet context types
|
||||
NONE = 0x00 # Generic data packet
|
||||
RESOURCE = 0x01 # Packet is part of a resource
|
||||
RESOURCE_ADV = 0x02 # Packet is a resource advertisement
|
||||
@ -68,7 +68,6 @@ class Packet:
|
||||
HEADER_MAXSIZE = RNS.Reticulum.HEADER_MAXSIZE
|
||||
MDU = RNS.Reticulum.MDU
|
||||
|
||||
# TODO: Update this
|
||||
# With an MTU of 500, the maximum of data we can
|
||||
# send in a single encrypted packet is given by
|
||||
# the below calculation; 383 bytes.
|
||||
@ -327,6 +326,7 @@ class PacketReceipt:
|
||||
# Creates a new packet receipt from a sent packet
|
||||
def __init__(self, packet):
|
||||
self.hash = packet.get_hash()
|
||||
self.truncated_hash = packet.getTruncatedHash()
|
||||
self.sent = True
|
||||
self.sent_at = time.time()
|
||||
self.timeout = Packet.TIMEOUT
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Sphinx build info version 1
|
||||
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
|
||||
config: 205a0b937612ce08d1a58b1cbb471256
|
||||
config: 966ae7177c1d48c9ee15971994c623b5
|
||||
tags: 645f666f9bcd5a90fca523b33c5a78b7
|
||||
|
@ -80,6 +80,17 @@ the link has been established.
|
||||
|
||||
This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Identify.py>`_.
|
||||
|
||||
.. _example-request:
|
||||
|
||||
Requests & Responses
|
||||
====================
|
||||
|
||||
The *Request* example explores sendig requests and receiving responses.
|
||||
|
||||
.. literalinclude:: ../../Examples/Request.py
|
||||
|
||||
This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Request.py>`_.
|
||||
|
||||
.. _example-filetransfer:
|
||||
|
||||
Filetransfer
|
||||
|
@ -1,6 +1,6 @@
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
|
||||
VERSION: '0.2.1 beta',
|
||||
VERSION: '0.2.2 beta',
|
||||
LANGUAGE: 'None',
|
||||
COLLAPSE_INDEX: false,
|
||||
BUILDER: 'html',
|
||||
|
@ -5,7 +5,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Examples — Reticulum Network Stack 0.2.1 beta documentation</title>
|
||||
<title>Examples — Reticulum Network Stack 0.2.2 beta documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
<li class="right" >
|
||||
<a href="reference.html" title="API Reference"
|
||||
accesskey="P">previous</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.1 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.2 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Examples</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -1362,6 +1362,295 @@ the link has been established.</p>
|
||||
</div>
|
||||
<p>This example can also be found at <a class="reference external" href="https://github.com/markqvist/Reticulum/blob/master/Examples/Identify.py">https://github.com/markqvist/Reticulum/blob/master/Examples/Identify.py</a>.</p>
|
||||
</div>
|
||||
<div class="section" id="requests-responses">
|
||||
<span id="example-request"></span><h2>Requests & Responses<a class="headerlink" href="#requests-responses" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The <em>Request</em> example explores sendig requests and receiving responses.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1">##########################################################</span>
|
||||
<span class="c1"># This RNS example demonstrates how to set perform #</span>
|
||||
<span class="c1"># requests and receive responses over a link. #</span>
|
||||
<span class="c1">##########################################################</span>
|
||||
|
||||
<span class="kn">import</span> <span class="nn">os</span>
|
||||
<span class="kn">import</span> <span class="nn">sys</span>
|
||||
<span class="kn">import</span> <span class="nn">time</span>
|
||||
<span class="kn">import</span> <span class="nn">random</span>
|
||||
<span class="kn">import</span> <span class="nn">argparse</span>
|
||||
<span class="kn">import</span> <span class="nn">RNS</span>
|
||||
|
||||
<span class="c1"># Let's define an app name. We'll use this for all</span>
|
||||
<span class="c1"># destinations we create. Since this echo example</span>
|
||||
<span class="c1"># is part of a range of example utilities, we'll put</span>
|
||||
<span class="c1"># them all within the app namespace "example_utilities"</span>
|
||||
<span class="n">APP_NAME</span> <span class="o">=</span> <span class="s2">"example_utilities"</span>
|
||||
|
||||
<span class="c1">##########################################################</span>
|
||||
<span class="c1">#### Server Part #########################################</span>
|
||||
<span class="c1">##########################################################</span>
|
||||
|
||||
<span class="c1"># A reference to the latest client link that connected</span>
|
||||
<span class="n">latest_client_link</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">random_text_generator</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">remote_identity_hash</span><span class="p">,</span> <span class="n">requested_at</span><span class="p">):</span>
|
||||
<span class="n">texts</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"They looked up"</span><span class="p">,</span> <span class="s2">"On each full moon"</span><span class="p">,</span> <span class="s2">"Becky was upset"</span><span class="p">,</span> <span class="s2">"I’ll stay away from it"</span><span class="p">,</span> <span class="s2">"The pet shop stocks everything"</span><span class="p">]</span>
|
||||
<span class="k">return</span> <span class="n">texts</span><span class="p">[</span><span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">texts</span><span class="p">)</span><span class="o">-</span><span class="mi">1</span><span class="p">)]</span>
|
||||
|
||||
<span class="c1"># This initialisation is executed when the users chooses</span>
|
||||
<span class="c1"># to run as a server</span>
|
||||
<span class="k">def</span> <span class="nf">server</span><span class="p">(</span><span class="n">configpath</span><span class="p">):</span>
|
||||
<span class="c1"># We must first initialise Reticulum</span>
|
||||
<span class="n">reticulum</span> <span class="o">=</span> <span class="n">RNS</span><span class="o">.</span><span class="n">Reticulum</span><span class="p">(</span><span class="n">configpath</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># Randomly create a new identity for our link example</span>
|
||||
<span class="n">server_identity</span> <span class="o">=</span> <span class="n">RNS</span><span class="o">.</span><span class="n">Identity</span><span class="p">()</span>
|
||||
|
||||
<span class="c1"># We create a destination that clients can connect to. We</span>
|
||||
<span class="c1"># want clients to create links to this destination, so we</span>
|
||||
<span class="c1"># need to create a "single" destination type.</span>
|
||||
<span class="n">server_destination</span> <span class="o">=</span> <span class="n">RNS</span><span class="o">.</span><span class="n">Destination</span><span class="p">(</span>
|
||||
<span class="n">server_identity</span><span class="p">,</span>
|
||||
<span class="n">RNS</span><span class="o">.</span><span class="n">Destination</span><span class="o">.</span><span class="n">IN</span><span class="p">,</span>
|
||||
<span class="n">RNS</span><span class="o">.</span><span class="n">Destination</span><span class="o">.</span><span class="n">SINGLE</span><span class="p">,</span>
|
||||
<span class="n">APP_NAME</span><span class="p">,</span>
|
||||
<span class="s2">"requestexample"</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="c1"># We configure a function that will get called every time</span>
|
||||
<span class="c1"># a new client creates a link to this destination.</span>
|
||||
<span class="n">server_destination</span><span class="o">.</span><span class="n">set_link_established_callback</span><span class="p">(</span><span class="n">client_connected</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># We register a request handler for handling incoming</span>
|
||||
<span class="c1"># requests over any established links.</span>
|
||||
<span class="n">server_destination</span><span class="o">.</span><span class="n">register_request_handler</span><span class="p">(</span>
|
||||
<span class="s2">"/random/text"</span><span class="p">,</span>
|
||||
<span class="n">response_generator</span> <span class="o">=</span> <span class="n">random_text_generator</span><span class="p">,</span>
|
||||
<span class="n">allow</span> <span class="o">=</span> <span class="n">RNS</span><span class="o">.</span><span class="n">Destination</span><span class="o">.</span><span class="n">ALLOW_ALL</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="c1"># Everything's ready!</span>
|
||||
<span class="c1"># Let's Wait for client requests or user input</span>
|
||||
<span class="n">server_loop</span><span class="p">(</span><span class="n">server_destination</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">server_loop</span><span class="p">(</span><span class="n">destination</span><span class="p">):</span>
|
||||
<span class="c1"># Let the user know that everything is ready</span>
|
||||
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span>
|
||||
<span class="s2">"Request example "</span><span class="o">+</span>
|
||||
<span class="n">RNS</span><span class="o">.</span><span class="n">prettyhexrep</span><span class="p">(</span><span class="n">destination</span><span class="o">.</span><span class="n">hash</span><span class="p">)</span><span class="o">+</span>
|
||||
<span class="s2">" running, waiting for a connection."</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">"Hit enter to manually send an announce (Ctrl-C to quit)"</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># We enter a loop that runs until the users exits.</span>
|
||||
<span class="c1"># If the user hits enter, we will announce our server</span>
|
||||
<span class="c1"># destination on the network, which will let clients</span>
|
||||
<span class="c1"># know how to create messages directed towards it.</span>
|
||||
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
|
||||
<span class="n">entered</span> <span class="o">=</span> <span class="nb">input</span><span class="p">()</span>
|
||||
<span class="n">destination</span><span class="o">.</span><span class="n">announce</span><span class="p">()</span>
|
||||
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">"Sent announce from "</span><span class="o">+</span><span class="n">RNS</span><span class="o">.</span><span class="n">prettyhexrep</span><span class="p">(</span><span class="n">destination</span><span class="o">.</span><span class="n">hash</span><span class="p">))</span>
|
||||
|
||||
<span class="c1"># When a client establishes a link to our server</span>
|
||||
<span class="c1"># destination, this function will be called with</span>
|
||||
<span class="c1"># a reference to the link.</span>
|
||||
<span class="k">def</span> <span class="nf">client_connected</span><span class="p">(</span><span class="n">link</span><span class="p">):</span>
|
||||
<span class="k">global</span> <span class="n">latest_client_link</span>
|
||||
|
||||
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">"Client connected"</span><span class="p">)</span>
|
||||
<span class="n">link</span><span class="o">.</span><span class="n">set_link_closed_callback</span><span class="p">(</span><span class="n">client_disconnected</span><span class="p">)</span>
|
||||
<span class="n">latest_client_link</span> <span class="o">=</span> <span class="n">link</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">client_disconnected</span><span class="p">(</span><span class="n">link</span><span class="p">):</span>
|
||||
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">"Client disconnected"</span><span class="p">)</span>
|
||||
|
||||
|
||||
<span class="c1">##########################################################</span>
|
||||
<span class="c1">#### Client Part #########################################</span>
|
||||
<span class="c1">##########################################################</span>
|
||||
|
||||
<span class="c1"># A reference to the server link</span>
|
||||
<span class="n">server_link</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
|
||||
<span class="c1"># This initialisation is executed when the users chooses</span>
|
||||
<span class="c1"># to run as a client</span>
|
||||
<span class="k">def</span> <span class="nf">client</span><span class="p">(</span><span class="n">destination_hexhash</span><span class="p">,</span> <span class="n">configpath</span><span class="p">):</span>
|
||||
<span class="c1"># We need a binary representation of the destination</span>
|
||||
<span class="c1"># hash that was entered on the command line</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">destination_hexhash</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">20</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"Destination length is invalid, must be 20 hexadecimal characters (10 bytes)"</span><span class="p">)</span>
|
||||
<span class="n">destination_hash</span> <span class="o">=</span> <span class="nb">bytes</span><span class="o">.</span><span class="n">fromhex</span><span class="p">(</span><span class="n">destination_hexhash</span><span class="p">)</span>
|
||||
<span class="k">except</span><span class="p">:</span>
|
||||
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">"Invalid destination entered. Check your input!</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="n">exit</span><span class="p">()</span>
|
||||
|
||||
<span class="c1"># We must first initialise Reticulum</span>
|
||||
<span class="n">reticulum</span> <span class="o">=</span> <span class="n">RNS</span><span class="o">.</span><span class="n">Reticulum</span><span class="p">(</span><span class="n">configpath</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># Check if we know a path to the destination</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">RNS</span><span class="o">.</span><span class="n">Transport</span><span class="o">.</span><span class="n">has_path</span><span class="p">(</span><span class="n">destination_hash</span><span class="p">):</span>
|
||||
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">"Destination is not yet known. Requesting path and waiting for announce to arrive..."</span><span class="p">)</span>
|
||||
<span class="n">RNS</span><span class="o">.</span><span class="n">Transport</span><span class="o">.</span><span class="n">request_path</span><span class="p">(</span><span class="n">destination_hash</span><span class="p">)</span>
|
||||
<span class="k">while</span> <span class="ow">not</span> <span class="n">RNS</span><span class="o">.</span><span class="n">Transport</span><span class="o">.</span><span class="n">has_path</span><span class="p">(</span><span class="n">destination_hash</span><span class="p">):</span>
|
||||
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.1</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># Recall the server identity</span>
|
||||
<span class="n">server_identity</span> <span class="o">=</span> <span class="n">RNS</span><span class="o">.</span><span class="n">Identity</span><span class="o">.</span><span class="n">recall</span><span class="p">(</span><span class="n">destination_hash</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># Inform the user that we'll begin connecting</span>
|
||||
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">"Establishing link with server..."</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># When the server identity is known, we set</span>
|
||||
<span class="c1"># up a destination</span>
|
||||
<span class="n">server_destination</span> <span class="o">=</span> <span class="n">RNS</span><span class="o">.</span><span class="n">Destination</span><span class="p">(</span>
|
||||
<span class="n">server_identity</span><span class="p">,</span>
|
||||
<span class="n">RNS</span><span class="o">.</span><span class="n">Destination</span><span class="o">.</span><span class="n">OUT</span><span class="p">,</span>
|
||||
<span class="n">RNS</span><span class="o">.</span><span class="n">Destination</span><span class="o">.</span><span class="n">SINGLE</span><span class="p">,</span>
|
||||
<span class="n">APP_NAME</span><span class="p">,</span>
|
||||
<span class="s2">"requestexample"</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="c1"># And create a link</span>
|
||||
<span class="n">link</span> <span class="o">=</span> <span class="n">RNS</span><span class="o">.</span><span class="n">Link</span><span class="p">(</span><span class="n">server_destination</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># We'll set up functions to inform the</span>
|
||||
<span class="c1"># user when the link is established or closed</span>
|
||||
<span class="n">link</span><span class="o">.</span><span class="n">set_link_established_callback</span><span class="p">(</span><span class="n">link_established</span><span class="p">)</span>
|
||||
<span class="n">link</span><span class="o">.</span><span class="n">set_link_closed_callback</span><span class="p">(</span><span class="n">link_closed</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># Everything is set up, so let's enter a loop</span>
|
||||
<span class="c1"># for the user to interact with the example</span>
|
||||
<span class="n">client_loop</span><span class="p">()</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">client_loop</span><span class="p">():</span>
|
||||
<span class="k">global</span> <span class="n">server_link</span>
|
||||
|
||||
<span class="c1"># Wait for the link to become active</span>
|
||||
<span class="k">while</span> <span class="ow">not</span> <span class="n">server_link</span><span class="p">:</span>
|
||||
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.1</span><span class="p">)</span>
|
||||
|
||||
<span class="n">should_quit</span> <span class="o">=</span> <span class="kc">False</span>
|
||||
<span class="k">while</span> <span class="ow">not</span> <span class="n">should_quit</span><span class="p">:</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="s2">"> "</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s2">" "</span><span class="p">)</span>
|
||||
<span class="n">text</span> <span class="o">=</span> <span class="nb">input</span><span class="p">()</span>
|
||||
|
||||
<span class="c1"># Check if we should quit the example</span>
|
||||
<span class="k">if</span> <span class="n">text</span> <span class="o">==</span> <span class="s2">"quit"</span> <span class="ow">or</span> <span class="n">text</span> <span class="o">==</span> <span class="s2">"q"</span> <span class="ow">or</span> <span class="n">text</span> <span class="o">==</span> <span class="s2">"exit"</span><span class="p">:</span>
|
||||
<span class="n">should_quit</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
<span class="n">server_link</span><span class="o">.</span><span class="n">teardown</span><span class="p">()</span>
|
||||
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">server_link</span><span class="o">.</span><span class="n">request</span><span class="p">(</span>
|
||||
<span class="s2">"/random/text"</span><span class="p">,</span>
|
||||
<span class="n">data</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">response_callback</span> <span class="o">=</span> <span class="n">got_response</span><span class="p">,</span>
|
||||
<span class="n">failed_callback</span> <span class="o">=</span> <span class="n">request_failed</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
|
||||
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
||||
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">"Error while sending request over the link: "</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
|
||||
<span class="n">should_quit</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
<span class="n">server_link</span><span class="o">.</span><span class="n">teardown</span><span class="p">()</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">got_response</span><span class="p">(</span><span class="n">request_receipt</span><span class="p">):</span>
|
||||
<span class="n">request_id</span> <span class="o">=</span> <span class="n">request_receipt</span><span class="o">.</span><span class="n">request_id</span>
|
||||
<span class="n">response</span> <span class="o">=</span> <span class="n">request_receipt</span><span class="o">.</span><span class="n">response</span>
|
||||
|
||||
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">"Got response for request "</span><span class="o">+</span><span class="n">RNS</span><span class="o">.</span><span class="n">prettyhexrep</span><span class="p">(</span><span class="n">request_id</span><span class="p">)</span><span class="o">+</span><span class="s2">": "</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">response</span><span class="p">))</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">request_received</span><span class="p">(</span><span class="n">request_receipt</span><span class="p">):</span>
|
||||
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">"The request "</span><span class="o">+</span><span class="n">RNS</span><span class="o">.</span><span class="n">prettyhexrep</span><span class="p">(</span><span class="n">request_receipt</span><span class="o">.</span><span class="n">request_id</span><span class="p">)</span><span class="o">+</span><span class="s2">" was received by the remote peer."</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">request_failed</span><span class="p">(</span><span class="n">request_receipt</span><span class="p">):</span>
|
||||
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">"The request "</span><span class="o">+</span><span class="n">RNS</span><span class="o">.</span><span class="n">prettyhexrep</span><span class="p">(</span><span class="n">request_receipt</span><span class="o">.</span><span class="n">request_id</span><span class="p">)</span><span class="o">+</span><span class="s2">" failed."</span><span class="p">)</span>
|
||||
|
||||
|
||||
<span class="c1"># This function is called when a link</span>
|
||||
<span class="c1"># has been established with the server</span>
|
||||
<span class="k">def</span> <span class="nf">link_established</span><span class="p">(</span><span class="n">link</span><span class="p">):</span>
|
||||
<span class="c1"># We store a reference to the link</span>
|
||||
<span class="c1"># instance for later use</span>
|
||||
<span class="k">global</span> <span class="n">server_link</span>
|
||||
<span class="n">server_link</span> <span class="o">=</span> <span class="n">link</span>
|
||||
|
||||
<span class="c1"># Inform the user that the server is</span>
|
||||
<span class="c1"># connected</span>
|
||||
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">"Link established with server, hit enter to perform a request, or type in </span><span class="se">\"</span><span class="s2">quit</span><span class="se">\"</span><span class="s2"> to quit"</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># When a link is closed, we'll inform the</span>
|
||||
<span class="c1"># user, and exit the program</span>
|
||||
<span class="k">def</span> <span class="nf">link_closed</span><span class="p">(</span><span class="n">link</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="n">link</span><span class="o">.</span><span class="n">teardown_reason</span> <span class="o">==</span> <span class="n">RNS</span><span class="o">.</span><span class="n">Link</span><span class="o">.</span><span class="n">TIMEOUT</span><span class="p">:</span>
|
||||
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">"The link timed out, exiting now"</span><span class="p">)</span>
|
||||
<span class="k">elif</span> <span class="n">link</span><span class="o">.</span><span class="n">teardown_reason</span> <span class="o">==</span> <span class="n">RNS</span><span class="o">.</span><span class="n">Link</span><span class="o">.</span><span class="n">DESTINATION_CLOSED</span><span class="p">:</span>
|
||||
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">"The link was closed by the server, exiting now"</span><span class="p">)</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">"Link closed, exiting now"</span><span class="p">)</span>
|
||||
|
||||
<span class="n">RNS</span><span class="o">.</span><span class="n">Reticulum</span><span class="o">.</span><span class="n">exit_handler</span><span class="p">()</span>
|
||||
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span>
|
||||
<span class="n">os</span><span class="o">.</span><span class="n">_exit</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
|
||||
|
||||
|
||||
<span class="c1">##########################################################</span>
|
||||
<span class="c1">#### Program Startup #####################################</span>
|
||||
<span class="c1">##########################################################</span>
|
||||
|
||||
<span class="c1"># This part of the program runs at startup,</span>
|
||||
<span class="c1"># and parses input of from the user, and then</span>
|
||||
<span class="c1"># starts up the desired program mode.</span>
|
||||
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">"__main__"</span><span class="p">:</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">parser</span> <span class="o">=</span> <span class="n">argparse</span><span class="o">.</span><span class="n">ArgumentParser</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s2">"Simple request/response example"</span><span class="p">)</span>
|
||||
|
||||
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span>
|
||||
<span class="s2">"-s"</span><span class="p">,</span>
|
||||
<span class="s2">"--server"</span><span class="p">,</span>
|
||||
<span class="n">action</span><span class="o">=</span><span class="s2">"store_true"</span><span class="p">,</span>
|
||||
<span class="n">help</span><span class="o">=</span><span class="s2">"wait for incoming requests from clients"</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span>
|
||||
<span class="s2">"--config"</span><span class="p">,</span>
|
||||
<span class="n">action</span><span class="o">=</span><span class="s2">"store"</span><span class="p">,</span>
|
||||
<span class="n">default</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">help</span><span class="o">=</span><span class="s2">"path to alternative Reticulum config directory"</span><span class="p">,</span>
|
||||
<span class="nb">type</span><span class="o">=</span><span class="nb">str</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span>
|
||||
<span class="s2">"destination"</span><span class="p">,</span>
|
||||
<span class="n">nargs</span><span class="o">=</span><span class="s2">"?"</span><span class="p">,</span>
|
||||
<span class="n">default</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">help</span><span class="o">=</span><span class="s2">"hexadecimal hash of the server destination"</span><span class="p">,</span>
|
||||
<span class="nb">type</span><span class="o">=</span><span class="nb">str</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="n">args</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse_args</span><span class="p">()</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">args</span><span class="o">.</span><span class="n">config</span><span class="p">:</span>
|
||||
<span class="n">configarg</span> <span class="o">=</span> <span class="n">args</span><span class="o">.</span><span class="n">config</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">configarg</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">args</span><span class="o">.</span><span class="n">server</span><span class="p">:</span>
|
||||
<span class="n">server</span><span class="p">(</span><span class="n">configarg</span><span class="p">)</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">destination</span> <span class="o">==</span> <span class="kc">None</span><span class="p">):</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
|
||||
<span class="n">parser</span><span class="o">.</span><span class="n">print_help</span><span class="p">()</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">client</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">destination</span><span class="p">,</span> <span class="n">configarg</span><span class="p">)</span>
|
||||
|
||||
<span class="k">except</span> <span class="ne">KeyboardInterrupt</span><span class="p">:</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
|
||||
<span class="n">exit</span><span class="p">()</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This example can also be found at <a class="reference external" href="https://github.com/markqvist/Reticulum/blob/master/Examples/Request.py">https://github.com/markqvist/Reticulum/blob/master/Examples/Request.py</a>.</p>
|
||||
</div>
|
||||
<div class="section" id="filetransfer">
|
||||
<span id="example-filetransfer"></span><h2>Filetransfer<a class="headerlink" href="#filetransfer" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The <em>Filetransfer</em> example implements a basic file-server program that
|
||||
@ -1504,7 +1793,12 @@ interface to efficiently pass files of any size over a Reticulum <a class="refer
|
||||
|
||||
<span class="k">def</span> <span class="nf">client_request</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">packet</span><span class="p">):</span>
|
||||
<span class="k">global</span> <span class="n">serve_path</span>
|
||||
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">filename</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">)</span>
|
||||
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
||||
<span class="n">filename</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">filename</span> <span class="ow">in</span> <span class="n">list_files</span><span class="p">():</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="c1"># If we have the requested file, we'll</span>
|
||||
@ -1986,6 +2280,7 @@ interface to efficiently pass files of any size over a Reticulum <a class="refer
|
||||
<li><a class="reference internal" href="#echo">Echo</a></li>
|
||||
<li><a class="reference internal" href="#link">Link</a></li>
|
||||
<li><a class="reference internal" href="#example-identify">Identification</a></li>
|
||||
<li><a class="reference internal" href="#requests-responses">Requests & Responses</a></li>
|
||||
<li><a class="reference internal" href="#filetransfer">Filetransfer</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
@ -2024,7 +2319,7 @@ interface to efficiently pass files of any size over a Reticulum <a class="refer
|
||||
<li class="right" >
|
||||
<a href="reference.html" title="API Reference"
|
||||
>previous</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.1 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.2 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Examples</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Index — Reticulum Network Stack 0.2.1 beta documentation</title>
|
||||
<title>Index — Reticulum Network Stack 0.2.2 beta documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="#" title="General Index"
|
||||
accesskey="I">index</a></li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.1 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.2 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Index</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -103,6 +103,8 @@
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="reference.html#RNS.Transport.deregister_announce_handler">deregister_announce_handler() (RNS.Transport static method)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#RNS.Destination.deregister_request_handler">deregister_request_handler() (RNS.Destination method)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#RNS.Destination">Destination (class in RNS)</a>
|
||||
</li>
|
||||
@ -261,9 +263,13 @@
|
||||
<li><a href="reference.html#RNS.Identity.recall_app_data">recall_app_data() (RNS.Identity static method)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#RNS.Transport.register_announce_handler">register_announce_handler() (RNS.Transport static method)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#RNS.Destination.register_request_handler">register_request_handler() (RNS.Destination method)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="reference.html#RNS.Link.request">request() (RNS.Link method)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#RNS.Transport.request_path">request_path() (RNS.Transport static method)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#RNS.Packet.resend">resend() (RNS.Packet method)</a>
|
||||
@ -381,7 +387,7 @@
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="#" title="General Index"
|
||||
>index</a></li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.1 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.2 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Index</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Getting Started Fast — Reticulum Network Stack 0.2.1 beta documentation</title>
|
||||
<title>Getting Started Fast — Reticulum Network Stack 0.2.2 beta documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
<li class="right" >
|
||||
<a href="whatis.html" title="What is Reticulum?"
|
||||
accesskey="P">previous</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.1 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.2 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Getting Started Fast</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -166,7 +166,7 @@ don’t use pip, but try this recipe:</p>
|
||||
<li class="right" >
|
||||
<a href="whatis.html" title="What is Reticulum?"
|
||||
>previous</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.1 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.2 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Getting Started Fast</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Reticulum Network Stack Manual — Reticulum Network Stack 0.2.1 beta documentation</title>
|
||||
<title>Reticulum Network Stack Manual — Reticulum Network Stack 0.2.2 beta documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
<li class="right" >
|
||||
<a href="whatis.html" title="What is Reticulum?"
|
||||
accesskey="N">next</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="#">Reticulum Network Stack 0.2.1 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-0"><a href="#">Reticulum Network Stack 0.2.2 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Reticulum Network Stack Manual</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -104,6 +104,7 @@ the development of Reticulum itself.</p>
|
||||
<li class="toctree-l2"><a class="reference internal" href="examples.html#echo">Echo</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="examples.html#link">Link</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="examples.html#example-identify">Identification</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="examples.html#requests-responses">Requests & Responses</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="examples.html#filetransfer">Filetransfer</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
@ -166,7 +167,7 @@ the development of Reticulum itself.</p>
|
||||
<li class="right" >
|
||||
<a href="whatis.html" title="What is Reticulum?"
|
||||
>next</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="#">Reticulum Network Stack 0.2.1 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-0"><a href="#">Reticulum Network Stack 0.2.2 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Reticulum Network Stack Manual</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
Binary file not shown.
@ -5,7 +5,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>API Reference — Reticulum Network Stack 0.2.1 beta documentation</title>
|
||||
<title>API Reference — Reticulum Network Stack 0.2.2 beta documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
<li class="right" >
|
||||
<a href="understanding.html" title="Understanding Reticulum"
|
||||
accesskey="P">previous</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.1 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.2 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">API Reference</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -508,6 +508,39 @@ proofs should be returned for received packets.</p>
|
||||
</dl>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="RNS.Destination.register_request_handler">
|
||||
<span class="sig-name descname"><span class="pre">register_request_handler</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">path</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">response_generator</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">allow</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">allowed_list</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Destination.register_request_handler" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Registers a request handler.</p>
|
||||
<dl class="field-list simple">
|
||||
<dt class="field-odd">Parameters</dt>
|
||||
<dd class="field-odd"><ul class="simple">
|
||||
<li><p><strong>path</strong> – The path for the request handler to be registered.</p></li>
|
||||
<li><p><strong>response_generator</strong> – A function or method with the signature <em>response_generator(path, data, remote_identity_hash, requested_at)</em> to be called. Whatever this funcion returns will be sent as a response to the requester. If the function returns <code class="docutils literal notranslate"><span class="pre">None</span></code>, no response will be sent.</p></li>
|
||||
<li><p><strong>allow</strong> – One of <code class="docutils literal notranslate"><span class="pre">RNS.Destination.ALLOW_NONE</span></code>, <code class="docutils literal notranslate"><span class="pre">RNS.Destination.ALLOW_ALL</span></code> or <code class="docutils literal notranslate"><span class="pre">RNS.Destination.ALLOW_LIST</span></code>. If <code class="docutils literal notranslate"><span class="pre">RNS.Destination.ALLOW_LIST</span></code> is set, the request handler will only respond to requests for identified peers in the supplied list.</p></li>
|
||||
<li><p><strong>allowed_list</strong> – A list of <em>bytes-like</em> <a class="reference internal" href="#api-identity"><span class="std std-ref">RNS.Identity</span></a> hashes.</p></li>
|
||||
</ul>
|
||||
</dd>
|
||||
<dt class="field-even">Raises</dt>
|
||||
<dd class="field-even"><p><code class="docutils literal notranslate"><span class="pre">ValueError</span></code> if any of the supplied arguments are invalid.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="RNS.Destination.deregister_request_handler">
|
||||
<span class="sig-name descname"><span class="pre">deregister_request_handler</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">path</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Destination.deregister_request_handler" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Deregisters a request handler.</p>
|
||||
<dl class="field-list simple">
|
||||
<dt class="field-odd">Parameters</dt>
|
||||
<dd class="field-odd"><p><strong>path</strong> – The path for the request handler to be deregistered.</p>
|
||||
</dd>
|
||||
<dt class="field-even">Returns</dt>
|
||||
<dd class="field-even"><p>True if the handler was deregistered, otherwise False.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="RNS.Destination.create_keys">
|
||||
<span class="sig-name descname"><span class="pre">create_keys</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Destination.create_keys" title="Permalink to this definition">¶</a></dt>
|
||||
@ -785,6 +818,21 @@ thus preserved. This method can be used for authentication.</p>
|
||||
</dl>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="RNS.Link.request">
|
||||
<span class="sig-name descname"><span class="pre">request</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">path</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">data</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">response_callback</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">failed_callback</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Link.request" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Sends a request to the remote peer.</p>
|
||||
<dl class="field-list simple">
|
||||
<dt class="field-odd">Parameters</dt>
|
||||
<dd class="field-odd"><ul class="simple">
|
||||
<li><p><strong>path</strong> – The request path.</p></li>
|
||||
<li><p><strong>response_callback</strong> – A function or method with the signature <em>response_callback(request_receipt)</em> to be called when a response is received. See the <a class="reference internal" href="examples.html#example-request"><span class="std std-ref">Request Example</span></a> for more info.</p></li>
|
||||
<li><p><strong>failed_callback</strong> – A function or method with the signature <em>failed_callback(request_receipt)</em> to be called when a request fails. See the <a class="reference internal" href="examples.html#example-request"><span class="std std-ref">Request Example</span></a> for more info.</p></li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="RNS.Link.no_inbound_for">
|
||||
<span class="sig-name descname"><span class="pre">no_inbound_for</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Link.no_inbound_for" title="Permalink to this definition">¶</a></dt>
|
||||
@ -934,7 +982,7 @@ compression, coordination and checksumming.</p>
|
||||
<dl class="field-list simple">
|
||||
<dt class="field-odd">Parameters</dt>
|
||||
<dd class="field-odd"><ul class="simple">
|
||||
<li><p><strong>data</strong> – The data to be transferred. Can be <em>bytes</em> or an open <em>file handle</em>. See the <span class="xref std std-ref">Filetransfer Example</span> for details.</p></li>
|
||||
<li><p><strong>data</strong> – The data to be transferred. Can be <em>bytes</em> or an open <em>file handle</em>. See the <a class="reference internal" href="examples.html#example-filetransfer"><span class="std std-ref">Filetransfer Example</span></a> for details.</p></li>
|
||||
<li><p><strong>link</strong> – The <a class="reference internal" href="#api-link"><span class="std std-ref">RNS.Link</span></a> instance on which to transfer the data.</p></li>
|
||||
<li><p><strong>advertise</strong> – Whether to automatically advertise the resource. Can be <em>True</em> or <em>False</em>.</p></li>
|
||||
<li><p><strong>auto_compress</strong> – Whether to auto-compress the resource. Can be <em>True</em> or <em>False</em>.</p></li>
|
||||
@ -1094,7 +1142,7 @@ will announce it.</p>
|
||||
<li class="right" >
|
||||
<a href="understanding.html" title="Understanding Reticulum"
|
||||
>previous</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.1 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.2 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">API Reference</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Search — Reticulum Network Stack 0.2.1 beta documentation</title>
|
||||
<title>Search — Reticulum Network Stack 0.2.2 beta documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="genindex.html" title="General Index"
|
||||
accesskey="I">index</a></li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.1 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.2 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Search</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -85,7 +85,7 @@
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="genindex.html" title="General Index"
|
||||
>index</a></li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.1 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.2 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Search</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
File diff suppressed because one or more lines are too long
@ -5,7 +5,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Understanding Reticulum — Reticulum Network Stack 0.2.1 beta documentation</title>
|
||||
<title>Understanding Reticulum — Reticulum Network Stack 0.2.2 beta documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
<li class="right" >
|
||||
<a href="gettingstartedfast.html" title="Getting Started Fast"
|
||||
accesskey="P">previous</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.1 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.2 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Understanding Reticulum</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -853,7 +853,7 @@ proof 11
|
||||
<li class="right" >
|
||||
<a href="gettingstartedfast.html" title="Getting Started Fast"
|
||||
>previous</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.1 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.2 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Understanding Reticulum</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>What is Reticulum? — Reticulum Network Stack 0.2.1 beta documentation</title>
|
||||
<title>What is Reticulum? — Reticulum Network Stack 0.2.2 beta documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
<li class="right" >
|
||||
<a href="index.html" title="Reticulum Network Stack Manual"
|
||||
accesskey="P">previous</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.1 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.2 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">What is Reticulum?</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -182,7 +182,7 @@ network, and vice versa.</p>
|
||||
<li class="right" >
|
||||
<a href="index.html" title="Reticulum Network Stack Manual"
|
||||
>previous</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.1 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.2 beta documentation</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">What is Reticulum?</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -22,7 +22,7 @@ copyright = '2021, Mark Qvist'
|
||||
author = 'Mark Qvist'
|
||||
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = '0.2.1 beta'
|
||||
release = '0.2.2 beta'
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
@ -80,6 +80,17 @@ the link has been established.
|
||||
|
||||
This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Identify.py>`_.
|
||||
|
||||
.. _example-request:
|
||||
|
||||
Requests & Responses
|
||||
====================
|
||||
|
||||
The *Request* example explores sendig requests and receiving responses.
|
||||
|
||||
.. literalinclude:: ../../Examples/Request.py
|
||||
|
||||
This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Request.py>`_.
|
||||
|
||||
.. _example-filetransfer:
|
||||
|
||||
Filetransfer
|
||||
|
Loading…
Reference in New Issue
Block a user