Parse Discovery Response Headers

This commit is contained in:
Florian Märkl 2019-08-07 21:54:25 +02:00
commit 84f91c2e21
No known key found for this signature in database
GPG key ID: 125BC8A5A6A1E857
6 changed files with 104 additions and 12 deletions

View file

@ -30,6 +30,7 @@
int RunDiscoveryCmd(const QString &host)
{
ChiakiLog log;
chiaki_log_init(&log, CHIAKI_LOG_ALL, chiaki_log_cb_print, NULL);
ChiakiDiscovery discovery;
ChiakiErrorCode err = chiaki_discovery_init(&discovery, &log, AF_INET); // TODO: IPv6

View file

@ -44,6 +44,24 @@ typedef struct chiaki_discovery_packet_t
char *protocol_version;
} ChiakiDiscoveryPacket;
typedef enum chiaki_discovery_host_state_t
{
CHIAKI_DISCOVERY_HOST_STATE_UNKNOWN,
CHIAKI_DISCOVERY_HOST_STATE_READY,
CHIAKI_DISCOVERY_HOST_STATE_STANDBY
} ChiakiDiscoveryHostState;
typedef struct chiaki_discovery_srch_response_t
{
ChiakiDiscoveryHostState state;
const char *system_version;
const char *device_discovery_protocol_version;
uint16_t host_request_port;
const char *host_name;
const char *host_type;
const char *host_id;
} ChiakiDiscoverySrchResponse;
CHIAKI_EXPORT int chiaki_discovery_packet_fmt(char *buf, size_t buf_size, ChiakiDiscoveryPacket *packet);
typedef struct chiaki_discovery_t

View file

@ -16,6 +16,7 @@
*/
#include <chiaki/discovery.h>
#include <chiaki/http.h>
#include <chiaki/log.h>
#include <string.h>
@ -38,6 +39,49 @@ CHIAKI_EXPORT int chiaki_discovery_packet_fmt(char *buf, size_t buf_size, Chiaki
}
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_srch_response_parse(ChiakiDiscoverySrchResponse *response, char *buf, size_t buf_size)
{
ChiakiHttpResponse http_response;
ChiakiErrorCode err = chiaki_http_response_parse(&http_response, buf, buf_size);
if(err != CHIAKI_ERR_SUCCESS)
return err;
memset(response, 0, sizeof(*response));
switch(http_response.code)
{
case 200:
response->state = CHIAKI_DISCOVERY_HOST_STATE_READY;
break;
case 620:
response->state = CHIAKI_DISCOVERY_HOST_STATE_STANDBY;
break;
default:
response->state = CHIAKI_DISCOVERY_HOST_STATE_UNKNOWN;
break;
}
for(ChiakiHttpHeader *header = http_response.headers; header; header=header->next)
{
printf("%s: %s\n", header->key, header->value);
if(strcmp(header->key, "system-version") == 0)
response->system_version = header->value;
else if(strcmp(header->key, "device-discovery-protocol-version") == 0)
response->device_discovery_protocol_version = header->value;
else if(strcmp(header->key, "host-request-port") == 0)
response->host_request_port = (uint16_t)strtoul(header->value, NULL, 0);
else if(strcmp(header->key, "host-name") == 0)
response->host_name = header->value;
else if(strcmp(header->key, "host-type") == 0)
response->host_type = header->value;
else if(strcmp(header->key, "host-id") == 0)
response->host_id = header->value;
}
chiaki_http_response_fini(&http_response);
return CHIAKI_ERR_SUCCESS;
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_init(ChiakiDiscovery *discovery, ChiakiLog *log, sa_family_t family)
{
if(family != AF_INET && family != AF_INET6)
@ -177,7 +221,13 @@ static void *discovery_thread_func(void *user)
buf[n] = '\00';
CHIAKI_LOGD(discovery->log, "Discovery received:\n%s", buf);
CHIAKI_LOGV(discovery->log, "Discovery received:\n%s", buf);
chiaki_log_hexdump_raw(discovery->log, CHIAKI_LOG_VERBOSE, (const uint8_t *)buf, n);
ChiakiDiscoverySrchResponse response;
err = chiaki_discovery_srch_response_parse(&response, buf, n);
if(err != CHIAKI_ERR_SUCCESS)
CHIAKI_LOGI(discovery->log, "Discovery Response invalid");
}
return NULL;

View file

@ -35,7 +35,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_service_init(ChiakiDiscoveryServi
ChiakiErrorCode err = chiaki_discovery_init(&service->discovery, log, service->options.send_addr->sa_family);
if(err != CHIAKI_ERR_SUCCESS)
goto error_servers;
goto error_send_addr;
err = chiaki_bool_pred_cond_init(&service->stop_cond);
if(err != CHIAKI_ERR_SUCCESS)

View file

@ -53,8 +53,9 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_http_header_parse(ChiakiHttpHeader **header
FAIL(CHIAKI_ERR_INVALID_DATA);
*buf = '\0';
buf++;
if(buf == end || *buf != ' ')
if(buf == end)
FAIL(CHIAKI_ERR_INVALID_DATA);
if(*buf == ' ')
buf++;
if(buf == end)
FAIL(CHIAKI_ERR_INVALID_DATA);
@ -113,12 +114,15 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_http_response_parse(ChiakiHttpResponse *res
buf += http_version_size;
buf_size -= http_version_size;
char *line_end = memchr(buf, '\r', buf_size);
char *line_end = memchr(buf, '\n', buf_size);
if(!line_end)
return CHIAKI_ERR_INVALID_DATA;
size_t line_length = (line_end - buf) + 2;
if(buf_size <= line_length || line_end[1] != '\n')
size_t line_length = (line_end - buf) + 1;
if(buf_size <= line_length)
return CHIAKI_ERR_INVALID_DATA;
if(line_length > 1 && *(line_end - 1) == '\r')
*(line_end - 1) = '\0';
else
*line_end = '\0';
char *endptr;

View file

@ -20,15 +20,25 @@
#include <chiaki/http.h>
#include <stdio.h>
static const char *response =
static char * const response_crlf =
"HTTP/1.1 200 OK\r\n"
"Content-type: text/html, text, plain\r\n"
"Ultimate Ability: Gamer\r\n"
"\r\n";
static char * const response_lf =
"HTTP/1.1 200 Ok\n"
"Content-type: text/html, text, plain\n"
"Ultimate Ability:Gamer\n";
static void *test_http_response_parse_setup(const MunitParameter params[], void *user)
{
return strdup(response);
const char *response = NULL;
if(strcmp(params[0].value, "crlf") == 0)
response = response_crlf;
else if(strcmp(params[0].value, "lf") == 0)
response = response_lf;
return response ? strdup(response) : NULL;
}
static void test_http_response_parse_teardown(void *fixture)
@ -61,6 +71,15 @@ static MunitResult test_http_response_parse(const MunitParameter params[], void
return MUNIT_OK;
}
static char *response_params[] = {
"crlf", "lf", NULL
};
static MunitParameterEnum params[] = {
{ "line ending", response_params },
{ NULL, NULL }
};
MunitTest tests_http[] = {
{
"/response_parse",
@ -68,7 +87,7 @@ MunitTest tests_http[] = {
test_http_response_parse_setup,
test_http_response_parse_teardown,
MUNIT_TEST_OPTION_NONE,
NULL
params
},
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
};