Remove http_block server

Issue #4405
This commit is contained in:
Norman Feske
2022-02-04 13:39:26 +01:00
parent 479f2e0d1f
commit 9478c3cc7c
6 changed files with 0 additions and 563 deletions

View File

@@ -395,10 +395,6 @@ Separate components
The terminal crosslink service allows to terminal clients to talk to each
other.
:_gems/src/server/http_block/_:
A block service that fetches a virtual block device over the network from
a HTTP server.
:_os/src/server/fs_rom/_:
A ROM service that translates the 'File_system' session interface to the
'ROM' session' interface. Each request for a ROM file is handled by looking

View File

@@ -1,16 +0,0 @@
This directory contains a HTTP client that implements Genode's block session
interface as a front-end. This way you can incorporate arbitrary files via.
HTTP requests and export them as a block device within Genode.
Usage
-----
Config file snippet:
!<start name="http_block">
! <resource name="RAM" quantum="1M" />
! <provides><service name="Block"/></provides> <!-- Mandatory -->
! <config uri="http://kc86.genode.labs:80/file.iso" block_size=2048/>
!</start>

View File

@@ -1,307 +0,0 @@
/*
* \brief HTTP protocol parts
* \author Sebastian Sumpf <Sebastian.Sumpf@genode-labs.com>
* \date 2010-08-19
*/
/*
* Copyright (C) 2010-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#include <base/child.h>
#include <base/log.h>
#include <base/sleep.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <netdb.h>
#include <errno.h>
#include "http.h"
using namespace Genode;
enum {
/* HTTP status codes */
HTTP_SUCC_OK = 200,
HTTP_SUCC_PARTIAL = 206,
/* Size of our local buffer */
HTTP_BUF = 2048,
};
/* Tokenizer policy */
struct Scanner_policy_file
{
static bool identifier_char(char c, unsigned /* i */)
{
return c != ':' && c != 0 && c != ' ' && c != '\n';
}
};
typedef ::Genode::Token<Scanner_policy_file> Http_token;
void Http::cmd_head()
{
const char *http_templ = "%s %s HTTP/1.1\r\n"
"Host: %s\r\n"
"\r\n";
int length = snprintf(_http_buf, HTTP_BUF, http_templ, "HEAD", _path, _host);
if (write(_fd, _http_buf, length) != length) {
error("cmd_head: write error");
throw Http::Socket_error();
}
}
void Http::connect()
{
_fd = socket(AF_INET, SOCK_STREAM, 0);
if (_fd < 0) {
error("connect: no socket avaiable");
throw Http::Socket_error();
}
if (::connect(_fd, _info->ai_addr, sizeof(*(_info->ai_addr))) < 0) {
error("connect: connect failed");
throw Http::Socket_error();
}
}
void Http::reconnect(){ close(_fd); connect(); }
void Http::resolve_uri()
{
struct addrinfo *info;
if (getaddrinfo(_host, _port, 0, &info)) {
error("host ", Cstring(_host), " not found");
throw Http::Uri_error();
}
_heap.try_alloc(sizeof(struct addrinfo)).with_result(
[&] (void *ptr) {
_info = (struct addrinfo *)ptr;
Genode::memcpy(_info, info, sizeof(struct addrinfo));
},
[&] (Allocator::Alloc_error) {
throw Http::Uri_error();
}
);
}
Genode::size_t Http::read_header()
{
bool header = true; size_t i = 0;
while (header) {
if (!read(_fd, &_http_buf[i], 1))
throw Http::Socket_closed();
if (i >= 3 && _http_buf[i - 3] == '\r' && _http_buf[i - 2] == '\n'
&& _http_buf[i - 1] == '\r' && _http_buf[i - 0] == '\n')
header = false;
if (++i >= HTTP_BUF) {
error("read_header: buffer overflow");
throw Http::Socket_error();
}
}
/* scan for status code */
Http_token t(_http_buf, i);
for (int count = 0;; t = t.next()) {
if (t.type() != Http_token::IDENT)
continue;
if (count) {
ascii_to(t.start(), _http_ret);
break;
}
count++;
}
return i;
}
void Http::get_capacity()
{
cmd_head();
size_t len = read_header();
char buf[32];
Http_token t(_http_buf, len);
bool key = false;
while (t) {
if (t.type() != Http_token::IDENT) {
t = t.next();
continue;
}
if (key) {
ascii_to(t.start(), _size);
break;
}
t.string(buf, 32);
if (!Genode::strcmp(buf, "Content-Length", 32))
key = true;
t = t.next();
}
}
void Http::do_read(void * buf, size_t size)
{
size_t buf_fill = 0;
while (buf_fill < size) {
int part;
if ((part = read(_fd, (void *)((addr_t)buf + buf_fill),
size - buf_fill)) <= 0) {
error("could not read data (", errno, ")");
throw Http::Socket_error();
}
buf_fill += part;
}
}
Http::Http(Genode::Heap &heap, ::String const &uri)
: _heap(heap), _port((char *)"80")
{
_heap.try_alloc(HTTP_BUF).with_result(
[&] (void *ptr) { _http_buf = (char *)ptr; },
[&] (Allocator::Alloc_error) { });
/* parse URI */
parse_uri(uri);
/* search for host */
resolve_uri();
/* connect to host */
connect();
/* retrieve file info */
get_capacity();
}
Http::~Http()
{
_heap.free(_host, Genode::strlen(_host) + 1);
_heap.free(_path, Genode::strlen(_path) + 2);
_heap.free(_http_buf, HTTP_BUF);
_heap.free(_info, sizeof(struct addrinfo));
}
void Http::parse_uri(::String const &u)
{
/* strip possible http prefix */
const char *http = "http://";
char * uri = const_cast<char*>(u.string());
size_t length = Genode::strlen(uri);
size_t http_len = Genode::strlen(http);
if (!strcmp(http, uri, http_len)) {
uri += http_len;
length -= http_len;
}
/* set host and file path */
size_t i;
for (i = 0; i < length && uri[i] != '/'; i++) ;
/*
* \param len number of cstring bytes w/o null-termination
*/
auto copied_cstring = [&] (char const *src, size_t len) -> char *
{
size_t const bytes = len + 1;
return _heap.try_alloc(bytes).convert<char *>(
[&] (void *ptr) {
char *dst = (char *)ptr;
copy_cstring(dst, src, bytes);
return dst; },
[&] (Allocator::Alloc_error) -> char * {
return nullptr; });
};
_host = copied_cstring(uri, i);
_path = copied_cstring(uri + i, length - i);
if (!_host || !_path) {
error("allocation failure during Http::parse_uri");
return;
}
/* look for port */
size_t len = Genode::strlen(_host);
for (i = 0; i < len && _host[i] != ':'; i++) ;
if (i < len) {
_port = &_host[i + 1];
_host[i] = '\0';
}
}
void Http::cmd_get(size_t file_offset, size_t size, addr_t buffer)
{
while (true) {
const char *http_templ = "GET %s HTTP/1.1\r\n"
"Host: %s\r\n"
"Range: bytes=%lu-%lu\r\n"
"\r\n";
int length = snprintf(_http_buf, HTTP_BUF, http_templ, _path, _host,
file_offset, file_offset + size - 1);
if (write(_fd, _http_buf, length) < 0) {
if (errno == ESHUTDOWN)
reconnect();
if (write(_fd, _http_buf, length) < 0)
throw Http::Socket_error();
}
try {
read_header();
} catch (Http::Socket_closed) {
reconnect();
continue;
}
if (_http_ret != HTTP_SUCC_PARTIAL) {
error("cmd_get: server returned ", _http_ret);
throw Http::Server_error();
}
do_read((void *)(buffer), size);
return;
}
}

View File

@@ -1,124 +0,0 @@
/*
* \brief HTTP back-end interface
* \author Sebastian Sumpf <Sebastian.Sumpf@genode-labs.com>
* \date 2010-08-24
*/
/*
* Copyright (C) 2010-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _HTTP_H_
#define _HTTP_H_
#include <base/stdint.h>
struct addrinfo;
using String = Genode::String<64>;
class Http
{
typedef Genode::size_t size_t;
typedef Genode::addr_t addr_t;
typedef Genode::off_t off_t;
private:
Genode::Heap &_heap;
size_t _size; /* number of bytes in file */
char *_host; /* host name */
char *_port; /* host port */
char *_path; /* absolute file path on host */
char *_http_buf; /* internal data buffer */
unsigned _http_ret; /* HTTP status code */
struct addrinfo *_info; /* Resolved address info for host */
int _fd; /* Socket file handle */
addr_t _base_addr; /* Address of I/O dataspace */
/*
* Send 'HEAD' command
*/
void cmd_head();
/*
* Connect to host
*/
void connect();
/*
* Re-connect to host
*/
void reconnect();
/*
* Set URI of remote file
*/
void parse_uri(::String const &uri);
/*
* Resolve host
*/
void resolve_uri();
/*
* Read HTTP header and parse server-status code
*/
size_t read_header();
/*
* Determine remote-file size
*/
void get_capacity();
/*
* Read 'size' bytes into buffer
*/
void do_read(void * buf, size_t size);
public:
/*
* Constructor (default host port is 80
*/
Http(Genode::Heap &heap, ::String const &uri);
/*
* Destructor
*/
~Http();
/**
* Read remote file size
*
* \return Remote file size in bytes
*/
size_t file_size() const { return _size; }
/**
* Set base address of I/O dataspace
*
* \param base_addr Base of dataspace
*/
void base_addr(addr_t base_addr) { _base_addr = base_addr; }
/**
* Send 'GET' command
*
* \param file_offset Read from offset of remote file
* \param size Number of byts to transfer
* \param buffer address in I/O dataspace
*/
void cmd_get(size_t file_offset, size_t size, addr_t buffer);
/* Exceptions */
class Exception : public ::Genode::Exception { };
class Uri_error : public Exception { };
class Socket_error : public Exception { };
class Socket_closed : public Exception { };
class Server_error : public Exception { };
};
#endif /* _HTTP_H_ */

View File

@@ -1,107 +0,0 @@
/*
* \brief Block interface for HTTP block driver
* \author Sebastian Sumpf <sebastian.sumpf@genode-labs.com>
* \author Stefan Kalkowski <stefan.kalkowski@genode-labs.com>
* \date 2010-08-24
*/
/*
* Copyright (C) 2010-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* Genode includes */
#include <base/attached_rom_dataspace.h>
#include <base/log.h>
#include <block/component.h>
#include <libc/component.h>
/* local includes */
#include "http.h"
using namespace Genode;
class Driver : public Block::Driver
{
private:
size_t _block_size;
Http _http;
public:
Driver(Heap &heap, Ram_allocator &ram,
size_t block_size, ::String const &uri)
: Block::Driver(ram),
_block_size(block_size), _http(heap, uri) {}
/*******************************
** Block::Driver interface **
*******************************/
Block::Session::Info info() const override
{
return { .block_size = _block_size,
.block_count = _http.file_size() / _block_size,
.align_log2 = log2(_block_size),
.writeable = false };
}
void read(Block::sector_t block_nr,
Genode::size_t block_count,
char *buffer,
Block::Packet_descriptor &packet)
{
_http.cmd_get(block_nr * _block_size, block_count * _block_size,
(addr_t)buffer);
ack_packet(packet);
}
};
class Factory : public Block::Driver_factory
{
private:
Env &_env;
Heap &_heap;
Attached_rom_dataspace _config { _env, "config" };
::String const _uri;
size_t const _blk_sz;
public:
Factory(Env &env, Heap &heap)
:
_env(env), _heap(heap),
_uri (_config.xml().attribute_value("uri", ::String())),
_blk_sz(_config.xml().attribute_value("block_size", 512U))
{
log("Using file=", _uri, " as device with block size ",
Hex(_blk_sz, Hex::OMIT_PREFIX), ".");
}
Block::Driver *create() {
return new (&_heap) Driver(_heap, _env.ram(), _blk_sz, _uri); }
void destroy(Block::Driver *driver) {
Genode::destroy(&_heap, driver); }
};
struct Main
{
Env &env;
Heap heap { env.ram(), env.rm() };
Factory factory { env, heap };
Block::Root root { env.ep(), heap, env.rm(), factory, true };
Main(Env &env) : env(env) {
env.parent().announce(env.ep().manage(root)); }
};
void Libc::Component::construct(Libc::Env &env) { static Main m(env); }

View File

@@ -1,5 +0,0 @@
TARGET = http_block
SRC_CC = main.cc http.cc
LIBS = libc
CC_CXX_WARN_STRICT =