mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-14 18:57:07 -07:00
Session HTTP Request
This commit is contained in:
parent
a81de8f7b5
commit
27286817db
9 changed files with 414 additions and 43 deletions
|
@ -3,12 +3,15 @@ set(HEADER_FILES
|
|||
include/chiaki/session.h
|
||||
include/chiaki/common.h
|
||||
include/chiaki/thread.h
|
||||
include/chiaki/base64.h)
|
||||
include/chiaki/base64.h
|
||||
include/chiaki/http.h)
|
||||
|
||||
set(SOURCE_FILES
|
||||
src/common.c
|
||||
src/session.c
|
||||
src/thread.c
|
||||
src/base64.c)
|
||||
src/base64.c
|
||||
src/http.c)
|
||||
|
||||
add_library(chiaki-lib ${HEADER_FILES} ${SOURCE_FILES})
|
||||
set_target_properties(chiaki-lib PROPERTIES OUTPUT_NAME chiaki)
|
||||
|
|
|
@ -24,6 +24,20 @@ extern "C" {
|
|||
|
||||
#define CHIAKI_EXPORT
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CHIAKI_ERR_SUCCESS = 0,
|
||||
CHIAKI_ERR_PARSE_ADDR = 1,
|
||||
CHIAKI_ERR_THREAD = 2,
|
||||
CHIAKI_ERR_MEMORY = 3,
|
||||
CHIAKI_ERR_NETWORK = 4,
|
||||
CHIAKI_ERR_INVALID_DATA = 5
|
||||
} ChiakiErrorCode;
|
||||
|
||||
CHIAKI_EXPORT const char *chiaki_error_string(ChiakiErrorCode code);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
55
lib/include/chiaki/http.h
Normal file
55
lib/include/chiaki/http.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* This file is part of Chiaki.
|
||||
*
|
||||
* Chiaki is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Chiaki is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Chiaki. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CHIAKI_HTTP_H
|
||||
#define CHIAKI_HTTP_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct chiaki_http_header_t
|
||||
{
|
||||
const char *key;
|
||||
const char *value;
|
||||
struct chiaki_http_header_t *next;
|
||||
} ChiakiHttpHeader;
|
||||
|
||||
typedef struct chiaki_http_response_t
|
||||
{
|
||||
int code;
|
||||
ChiakiHttpHeader *headers;
|
||||
} ChiakiHttpResponse;
|
||||
|
||||
CHIAKI_EXPORT void chiaki_http_header_free(ChiakiHttpHeader *header);
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_http_header_parse(ChiakiHttpHeader **header, char *buf, size_t buf_size);
|
||||
|
||||
CHIAKI_EXPORT void chiaki_http_response_fini(ChiakiHttpResponse *response);
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_http_response_parse(ChiakiHttpResponse *response, char *buf, size_t buf_size);
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_recv_http_header(int sock, char *buf, size_t buf_size, size_t *header_size, size_t *received_size);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // CHIAKI_HTTP_H
|
|
@ -22,6 +22,7 @@
|
|||
#include "thread.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -40,7 +41,8 @@ typedef struct chiaki_session_t
|
|||
{
|
||||
struct
|
||||
{
|
||||
char *host;
|
||||
struct addrinfo *host_addrinfos;
|
||||
struct addrinfo *host_addrinfo_selected;
|
||||
char *regist_key;
|
||||
char *ostype;
|
||||
char auth[0x10];
|
||||
|
@ -50,10 +52,10 @@ typedef struct chiaki_session_t
|
|||
ChiakiThread session_thread;
|
||||
} ChiakiSession;
|
||||
|
||||
CHIAKI_EXPORT void chiaki_session_init(ChiakiSession *session, ChiakiConnectInfo *connect_info);
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_session_init(ChiakiSession *session, ChiakiConnectInfo *connect_info);
|
||||
CHIAKI_EXPORT void chiaki_session_fini(ChiakiSession *session);
|
||||
CHIAKI_EXPORT bool chiaki_session_start(ChiakiSession *session);
|
||||
CHIAKI_EXPORT void chiaki_session_join(ChiakiSession *session);
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_session_start(ChiakiSession *session);
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_session_join(ChiakiSession *session);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -35,8 +33,8 @@ typedef struct chiaki_thread_t
|
|||
|
||||
typedef void *(*ChiakiThreadFunc)(void *);
|
||||
|
||||
CHIAKI_EXPORT bool chiaki_thread_create(ChiakiThread *thread, ChiakiThreadFunc func, void *arg);
|
||||
CHIAKI_EXPORT bool chiaki_thread_join(ChiakiThread *thread, void **retval);
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_thread_create(ChiakiThread *thread, ChiakiThreadFunc func, void *arg);
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_thread_join(ChiakiThread *thread, void **retval);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
39
lib/src/common.c
Normal file
39
lib/src/common.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* This file is part of Chiaki.
|
||||
*
|
||||
* Chiaki is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Chiaki is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Chiaki. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <chiaki/common.h>
|
||||
|
||||
CHIAKI_EXPORT const char *chiaki_error_string(ChiakiErrorCode code)
|
||||
{
|
||||
switch(code)
|
||||
{
|
||||
case CHIAKI_ERR_SUCCESS:
|
||||
return "Success";
|
||||
case CHIAKI_ERR_PARSE_ADDR:
|
||||
return "Failed to parse host address";
|
||||
case CHIAKI_ERR_THREAD:
|
||||
return "Thread error";
|
||||
case CHIAKI_ERR_MEMORY:
|
||||
return "Memory error";
|
||||
case CHIAKI_ERR_NETWORK:
|
||||
return "Network error";
|
||||
case CHIAKI_ERR_INVALID_DATA:
|
||||
return "Invalid data";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
126
lib/src/http.c
Normal file
126
lib/src/http.c
Normal file
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* This file is part of Chiaki.
|
||||
*
|
||||
* Chiaki is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Chiaki is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Chiaki. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <chiaki/http.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
|
||||
CHIAKI_EXPORT void chiaki_http_header_free(ChiakiHttpHeader *header)
|
||||
{
|
||||
while(header)
|
||||
{
|
||||
ChiakiHttpHeader *cur = header;
|
||||
header = header->next;
|
||||
free(cur);
|
||||
}
|
||||
}
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_http_header_parse(ChiakiHttpHeader **header, char *buf, size_t buf_size)
|
||||
{
|
||||
*header = NULL;
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
CHIAKI_EXPORT void chiaki_http_response_fini(ChiakiHttpResponse *response)
|
||||
{
|
||||
if(!response)
|
||||
return;
|
||||
chiaki_http_header_free(response->headers);
|
||||
}
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_http_response_parse(ChiakiHttpResponse *response, char *buf, size_t buf_size)
|
||||
{
|
||||
static const char *http_version = "HTTP/1.1 ";
|
||||
static const size_t http_version_size = 9;
|
||||
|
||||
if(buf_size < http_version_size)
|
||||
return CHIAKI_ERR_INVALID_DATA;
|
||||
|
||||
if(strncmp(buf, http_version, http_version_size) != 0)
|
||||
return CHIAKI_ERR_INVALID_DATA;
|
||||
|
||||
buf += http_version_size;
|
||||
buf_size -= http_version_size;
|
||||
|
||||
char *line_end = memchr(buf, '\r', 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')
|
||||
return CHIAKI_ERR_INVALID_DATA;
|
||||
*line_end = '\0';
|
||||
|
||||
char *endptr;
|
||||
response->code = (int)strtol(buf, &endptr, 10);
|
||||
if(response->code == 0)
|
||||
return CHIAKI_ERR_INVALID_DATA;
|
||||
|
||||
buf += line_length;
|
||||
buf_size -= line_length;
|
||||
|
||||
return chiaki_http_header_parse(&response->headers, buf, buf_size);
|
||||
}
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_recv_http_header(int sock, char *buf, size_t buf_size, size_t *header_size, size_t *received_size)
|
||||
{
|
||||
// 0 = ""
|
||||
// 1 = "\r"
|
||||
// 2 = "\r\n"
|
||||
// 3 = "\r\n\r"
|
||||
// 4 = "\r\n\r\n" (final)
|
||||
int nl_state = 0;
|
||||
static const int transitions_r[] = { 1, 1, 3, 1 };
|
||||
static const int transitions_n[] = { 0, 2, 0, 4 };
|
||||
|
||||
*received_size = 0;
|
||||
while(true)
|
||||
{
|
||||
ssize_t received = recv(sock, buf, buf_size, 0);
|
||||
if(received <= 0)
|
||||
return CHIAKI_ERR_NETWORK;
|
||||
|
||||
*received_size += received;
|
||||
for(; received > 0; buf++, received--)
|
||||
{
|
||||
switch(*buf)
|
||||
{
|
||||
case '\r':
|
||||
nl_state = transitions_r[nl_state];
|
||||
break;
|
||||
case '\n':
|
||||
nl_state = transitions_n[nl_state];
|
||||
break;
|
||||
default:
|
||||
nl_state = 0;
|
||||
break;
|
||||
}
|
||||
if(nl_state == 4)
|
||||
break;
|
||||
}
|
||||
|
||||
if(nl_state == 4)
|
||||
{
|
||||
*header_size = *received_size - received;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
}
|
|
@ -16,58 +16,198 @@
|
|||
*/
|
||||
|
||||
#include <chiaki/session.h>
|
||||
#include <chiaki/http.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
|
||||
static const char session_request[] =
|
||||
"GET /sce/rp/session HTTP/1.1\r\n"
|
||||
"Host: 192.168. 1. 8:9295\r\n"
|
||||
"User-Agent: remoteplay Windows\r\n"
|
||||
"Connection: close\r\n"
|
||||
"Content-Length: 0\r\n"
|
||||
"RP-Registkey: 3131633065363864\r\n"
|
||||
"Rp-Version: 8.0\r\n"
|
||||
"\r\n";
|
||||
#define SESSION_PORT 9295
|
||||
|
||||
|
||||
|
||||
static void *session_thread_func(void *arg);
|
||||
|
||||
|
||||
CHIAKI_EXPORT void chiaki_session_init(ChiakiSession *session, ChiakiConnectInfo *connect_info)
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_session_init(ChiakiSession *session, ChiakiConnectInfo *connect_info)
|
||||
{
|
||||
session->connect_info.host = strdup(connect_info->host);
|
||||
memset(session, 0, sizeof(ChiakiSession));
|
||||
|
||||
int r = getaddrinfo(connect_info->host, NULL, NULL, &session->connect_info.host_addrinfos);
|
||||
if(r != 0)
|
||||
{
|
||||
chiaki_session_fini(session);
|
||||
return CHIAKI_ERR_PARSE_ADDR;
|
||||
}
|
||||
|
||||
session->connect_info.regist_key = strdup(connect_info->regist_key);
|
||||
if(!session->connect_info.regist_key)
|
||||
{
|
||||
chiaki_session_fini(session);
|
||||
return CHIAKI_ERR_MEMORY;
|
||||
}
|
||||
|
||||
session->connect_info.ostype = strdup(connect_info->ostype);
|
||||
if(!session->connect_info.regist_key)
|
||||
{
|
||||
chiaki_session_fini(session);
|
||||
return CHIAKI_ERR_MEMORY;
|
||||
}
|
||||
|
||||
memcpy(session->connect_info.auth, connect_info->auth, sizeof(session->connect_info.auth));
|
||||
memcpy(session->connect_info.morning, connect_info->morning, sizeof(session->connect_info.morning));
|
||||
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
CHIAKI_EXPORT void chiaki_session_fini(ChiakiSession *session)
|
||||
{
|
||||
free(session->connect_info.host);
|
||||
if(!session)
|
||||
return;
|
||||
free(session->connect_info.regist_key);
|
||||
free(session->connect_info.ostype);
|
||||
freeaddrinfo(session->connect_info.host_addrinfos);
|
||||
}
|
||||
|
||||
CHIAKI_EXPORT bool chiaki_session_start(ChiakiSession *session)
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_session_start(ChiakiSession *session)
|
||||
{
|
||||
bool r = chiaki_thread_create(&session->session_thread, session_thread_func, session);
|
||||
if(!r)
|
||||
return false;
|
||||
return true;
|
||||
return chiaki_thread_create(&session->session_thread, session_thread_func, session);
|
||||
}
|
||||
|
||||
CHIAKI_EXPORT void chiaki_session_join(ChiakiSession *session)
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_session_join(ChiakiSession *session)
|
||||
{
|
||||
chiaki_thread_join(&session->session_thread, NULL);
|
||||
return chiaki_thread_join(&session->session_thread, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static ChiakiErrorCode session_thread_request_session(ChiakiSession *session);
|
||||
|
||||
static void *session_thread_func(void *arg)
|
||||
{
|
||||
ChiakiSession *session = arg;
|
||||
printf("Sleepy...\n");
|
||||
ChiakiErrorCode err;
|
||||
|
||||
err = session_thread_request_session(session);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static ChiakiErrorCode session_thread_request_session(ChiakiSession *session)
|
||||
{
|
||||
int session_sock = -1;
|
||||
char host_buf[128];
|
||||
for(struct addrinfo *ai=session->connect_info.host_addrinfos; ai; ai=ai->ai_next)
|
||||
{
|
||||
struct sockaddr *sa = malloc(ai->ai_addrlen);
|
||||
if(!sa)
|
||||
continue;
|
||||
memcpy(sa, ai->ai_addr, ai->ai_addrlen);
|
||||
|
||||
if(sa->sa_family == AF_INET)
|
||||
((struct sockaddr_in *)sa)->sin_port = htons(SESSION_PORT);
|
||||
else if(sa->sa_family == AF_INET6)
|
||||
((struct sockaddr_in6 *)sa)->sin6_port = htons(SESSION_PORT);
|
||||
else
|
||||
{
|
||||
free(sa);
|
||||
continue;
|
||||
}
|
||||
|
||||
int r = getnameinfo(sa, ai->ai_addrlen, host_buf, sizeof(host_buf), NULL, 0, 0);
|
||||
if(r != 0)
|
||||
{
|
||||
free(sa);
|
||||
continue;
|
||||
}
|
||||
|
||||
session_sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||
if(session_sock < 0)
|
||||
continue;
|
||||
r = connect(session_sock, sa, ai->ai_addrlen);
|
||||
if(r < 0)
|
||||
{
|
||||
close(session_sock);
|
||||
session_sock = -1;
|
||||
free(sa);
|
||||
continue;
|
||||
}
|
||||
free(sa);
|
||||
|
||||
session->connect_info.host_addrinfo_selected = ai;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if(session_sock < 0)
|
||||
{
|
||||
printf("Session Connection Failed.\n");
|
||||
return CHIAKI_ERR_NETWORK;
|
||||
}
|
||||
|
||||
printf("Connected to %s:%u\n", host_buf, SESSION_PORT);
|
||||
|
||||
|
||||
static const char session_request_fmt[] =
|
||||
"GET /sce/rp/session HTTP/1.1\r\n"
|
||||
"Host: %s:%d\r\n"
|
||||
"User-Agent: remoteplay Windows\r\n"
|
||||
"Connection: close\r\n"
|
||||
"Content-Length: 0\r\n"
|
||||
"RP-Registkey: %s\r\n"
|
||||
"Rp-Version: 8.0\r\n"
|
||||
"\r\n";
|
||||
|
||||
char buf[512];
|
||||
int request_len = snprintf(buf, sizeof(buf), session_request_fmt,
|
||||
host_buf, SESSION_PORT, session->connect_info.regist_key);
|
||||
if(request_len < 0 || request_len >= sizeof(buf))
|
||||
{
|
||||
printf("Session Request Building Failed.\n");
|
||||
close(session_sock);
|
||||
return CHIAKI_ERR_MEMORY;
|
||||
}
|
||||
|
||||
printf("sending\n%s\n", buf);
|
||||
|
||||
ssize_t sent = send(session_sock, buf, (size_t)request_len, 0);
|
||||
if(sent < 0)
|
||||
{
|
||||
printf("Session Request Send Failed.\n");
|
||||
perror("send");
|
||||
close(session_sock);
|
||||
return CHIAKI_ERR_NETWORK;
|
||||
}
|
||||
|
||||
size_t header_size;
|
||||
size_t received_size;
|
||||
ChiakiErrorCode err = chiaki_recv_http_header(session_sock, buf, sizeof(buf), &header_size, &received_size);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
{
|
||||
close(session_sock);
|
||||
return err;
|
||||
}
|
||||
|
||||
buf[received_size] = '\0';
|
||||
printf("received\n%s\n", buf);
|
||||
|
||||
ChiakiHttpResponse response;
|
||||
err = chiaki_http_response_parse(&response, buf, header_size);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
{
|
||||
close(session_sock);
|
||||
return err;
|
||||
}
|
||||
|
||||
close(session_sock);
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,24 +20,18 @@
|
|||
#include <stdio.h>
|
||||
|
||||
|
||||
CHIAKI_EXPORT bool chiaki_thread_create(ChiakiThread *thread, ChiakiThreadFunc func, void *arg)
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_thread_create(ChiakiThread *thread, ChiakiThreadFunc func, void *arg)
|
||||
{
|
||||
int r = pthread_create(&thread->thread, NULL, func, arg);
|
||||
if(r != 0)
|
||||
{
|
||||
perror("pthread_create");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return CHIAKI_ERR_THREAD;
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
CHIAKI_EXPORT bool chiaki_thread_join(ChiakiThread *thread, void **retval)
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_thread_join(ChiakiThread *thread, void **retval)
|
||||
{
|
||||
int r = pthread_join(thread->thread, retval);
|
||||
if(r != 0)
|
||||
{
|
||||
perror("pthread_join");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return CHIAKI_ERR_THREAD;
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue