/*
* \brief HTTP client test
* \author Ivan Loskutov
* \author Martin Stein
* \date 2012-12-21
*/
/*
* Copyright (C) 2012 Ksys Labs LLC
* Copyright (C) 2012-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
#include
#include
#include
#include
#include
/* Libc includes */
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace Genode;
void close_socket(Libc::Env &env, int sd)
{
if (::shutdown(sd, SHUT_RDWR)) {
error("failed to shutdown");
env.parent().exit(-1);
}
if (::close(sd)) {
error("failed to close");
env.parent().exit(-1);
}
}
static void test(Libc::Env &env)
{
using Ipv4_string = String<16>;
enum { NR_OF_REPLIES = 5 };
enum { NR_OF_TRIALS = 15 };
/* read component configuration */
Attached_rom_dataspace config_rom { env, "config" };
Xml_node config_node { config_rom.xml() };
Ipv4_string const srv_ip { config_node.attribute_value("server_ip", Ipv4_string("0.0.0.0")) };
uint16_t const srv_port { config_node.attribute_value("server_port", (uint16_t)0) };
/* construct server socket address */
struct sockaddr_in srv_addr;
srv_addr.sin_port = htons(srv_port);
srv_addr.sin_family = AF_INET;
srv_addr.sin_addr.s_addr = inet_addr(srv_ip.string());
/* try several times to request a reply */
for (unsigned trial_cnt = 0, reply_cnt = 0; trial_cnt < NR_OF_TRIALS;
trial_cnt++)
{
/* pause a while between each trial */
usleep(1000000);
/* create socket */
int sd = ::socket(AF_INET, SOCK_STREAM, 0);
if (sd < 0) {
error("failed to create socket");
continue;
}
/* connect to server */
if (::connect(sd, (struct sockaddr *)&srv_addr, sizeof(srv_addr))) {
error("Failed to connect to server");
close_socket(env, sd);
continue;
}
/* send request */
char const *req = "GET / HTTP/1.0\r\nHost: localhost:80\r\n\r\n";
size_t const req_sz = Genode::strlen(req);
if (::send(sd, req, req_sz, 0) != (int)req_sz) {
error("failed to send request");
close_socket(env, sd);
continue;
}
/* receive reply */
enum { REPLY_BUF_SZ = 1024 };
char reply_buf[REPLY_BUF_SZ];
size_t reply_sz = 0;
bool reply_failed = false;
char const *reply_end = "