Skip to content

Commit

Permalink
New message handling, and new NvAPI
Browse files Browse the repository at this point in the history
  • Loading branch information
dead committed Feb 25, 2016
1 parent f423fc6 commit c420db5
Show file tree
Hide file tree
Showing 17 changed files with 6,884 additions and 376 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
user-data-dir/
pnacl/

# Object files
*.o
*.ko
Expand Down
7 changes: 5 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ TARGET = moonlight-chrome
include common-c.mk
include opus.mk
include h264bitstream.mk
include libgamestream.mk

EXTRA_INC_PATHS := $(EXTRA_INC_PATHS) $(COMMON_C_INCLUDE) $(OPUS_INCLUDE) $(H264BS_INCLUDE)
EXTRA_INC_PATHS := $(EXTRA_INC_PATHS) $(COMMON_C_INCLUDE) $(OPUS_INCLUDE) $(H264BS_INCLUDE) $(LIBGS_C_INCLUDE)

include $(NACL_SDK_ROOT)/tools/common.mk

Expand All @@ -16,21 +17,23 @@ HTTPD_PY := $(HTTPD_PY) --no-dir-check

CHROME_ARGS += --allow-nacl-socket-api=localhost

LIBS = ppapi_gles2 ppapi ppapi_cpp pthread nacl_io
LIBS = ppapi_gles2 ppapi ppapi_cpp pthread curl z ssl crypto nacl_io

CFLAGS = -Wall $(COMMON_C_C_FLAGS) $(OPUS_C_FLAGS)

SOURCES = \
$(OPUS_SOURCE) \
$(H264BS_SOURCE) \
$(COMMON_C_SOURCE) \
$(LIBGS_C_SOURCE) \
libchelper.c \
main.cpp \
input.cpp \
gamepad.cpp \
connectionlistener.cpp \
viddec.cpp \
auddec.cpp \
http.cpp \

# Build rules generated by macros from common.mk:

Expand Down
125 changes: 125 additions & 0 deletions http.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#include "moonlight.hpp"

#include "ppapi/cpp/var_array_buffer.h"

#include <http.h>
#include "libgamestream/errors.h" //fix-me

#include <string.h>

#include <mkcert.h>
#include <openssl/bio.h>
#include <openssl/pem.h>

extern const char* gs_error;
X509 *g_cert;
EVP_PKEY *g_privateKey;

void MoonlightInstance::MakeCert(int32_t callbackId, pp::VarArray args)
{
pp::VarDictionary ret;
ret.Set("callbackId", pp::Var(callbackId));
ret.Set("type", pp::Var("resolve"));

pp::VarDictionary retData;

CERT_KEY_PAIR certKeyPair = mkcert_generate();

BIO* bio = BIO_new(BIO_s_mem());

PEM_write_bio_X509(bio, certKeyPair.x509);
BUF_MEM *mem = NULL;
BIO_get_mem_ptr(bio, &mem);

std::string cert(mem->data, mem->length);

BIO_free(bio);

BIO* biokey = BIO_new(BIO_s_mem());
PEM_write_bio_PrivateKey(biokey, certKeyPair.pkey, NULL, NULL, 0, NULL, NULL);
BIO_get_mem_ptr(biokey, &mem);

std::string pkey(mem->data, mem->length);

BIO_free(biokey);

retData.Set("privateKey", pkey.c_str());
retData.Set("cert", cert.c_str());

ret.Set("ret", retData);
PostMessage(ret);
}

void MoonlightInstance::LoadCert(const char* certStr, const char* keyStr)
{
char* _certStr = strdup(certStr);
char* _keyStr = strdup(keyStr);

BIO *bio = BIO_new_mem_buf(_certStr, -1);
if(!(g_cert = PEM_read_bio_X509(bio, NULL, NULL, NULL))) {
PostMessage(pp::Var("Error loading cert into memory"));
}
BIO_reset(bio);
BIO_free_all(bio);

bio = BIO_new_mem_buf(_keyStr, -1);
if(PEM_read_bio_PrivateKey(bio, &g_privateKey, NULL, NULL) == NULL) {
PostMessage(pp::Var("Error loading private key into memory"));
}
BIO_free_all(bio);

free(_certStr);
free(_keyStr);
}

void MoonlightInstance::NvHTTPInit(int32_t callbackId, pp::VarArray args)
{
std::string _cert = args.Get(0).AsString();
std::string _key = args.Get(1).AsString();

LoadCert(_cert.c_str(), _key.c_str());

http_init();

pp::VarDictionary ret;
ret.Set("callbackId", pp::Var(callbackId));
ret.Set("type", pp::Var("resolve"));
ret.Set("ret", pp::Var(""));
PostMessage(ret);
}

void MoonlightInstance::NvHTTPRequest(int32_t /*result*/, int32_t callbackId, std::string url)
{
char* _url = strdup(url.c_str());
PHTTP_DATA data = http_create_data();

if (data == NULL) {
pp::VarDictionary ret;
ret.Set("callbackId", pp::Var(callbackId));
ret.Set("type", pp::Var("reject"));
ret.Set("ret", pp::Var("Error when creating data buffer."));
PostMessage(ret);
goto clean_data;
}

if(http_request(_url , data) != GS_OK) {
pp::VarDictionary ret;
ret.Set("callbackId", pp::Var(callbackId));
ret.Set("type", pp::Var("reject"));
ret.Set("ret", pp::Var(gs_error));
PostMessage(ret);
goto clean_data;
}

{
pp::VarDictionary ret;
ret.Set("callbackId", pp::Var(callbackId));
ret.Set("type", pp::Var("resolve"));
ret.Set("ret", pp::Var(data->memory));
PostMessage(ret);
}

clean_data:
http_free_data(data);
free(_url);
}
5 changes: 4 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<div id="streamSettings">
<div class="mdl-select">
<select id="selectResolution">
<option selected="NONE">Stream Resolution</option>
<option value="NONE">Stream Resolution</option>
<option value="1280:720">1280x720</option>
<option value="1920:1080">1920x1080</option>
</select>
Expand Down Expand Up @@ -82,7 +82,10 @@
</div>
<script defer src="static/js/jquery-2.2.0.min.js"></script>
<script defer src="static/js/material.min.js"></script>
<script defer src="static/js/crypto-js.js"></script>
<script type="text/javascript" src="static/js/messages.js"></script>
<script type="text/javascript" src="static/js/common.js"></script>
<script type="text/javascript" src="static/js/index.js"></script>
<script type="text/javascript" src="static/js/utils.js"></script>
</body>
</html>
8 changes: 8 additions & 0 deletions libgamestream.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
LIBGS_C_DIR := libgamestream

LIBGS_C_SOURCE := \
$(LIBGS_C_DIR)/http.c \
$(LIBGS_C_DIR)/mkcert.c \

LIBGS_C_INCLUDE := \
$(LIBGS_C_DIR) \
29 changes: 29 additions & 0 deletions libgamestream/errors.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* This file is part of Moonlight Embedded.
*
* Copyright (C) 2015 Iwan Timmer
*
* Moonlight 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.
*
* Moonlight 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 Moonlight; if not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#define GS_OK 0
#define GS_FAILED -1
#define GS_OUT_OF_MEMORY -2
#define GS_INVALID -3
#define GS_WRONG_STATE -4
#define GS_IO_ERROR -5
#define GS_NOT_SUPPORTED_4K -6

138 changes: 138 additions & 0 deletions libgamestream/http.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/*
* This file is part of Moonlight Embedded.
*
* Copyright (C) 2015 Iwan Timmer
*
* Moonlight 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.
*
* Moonlight 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 Moonlight; if not, see <http://www.gnu.org/licenses/>.
*/

#include "http.h"
#include "errors.h"

#include <string.h>
#include <curl/curl.h>

#include <openssl/ssl.h>
#include <openssl/x509v3.h>
#include <openssl/pem.h>

static CURL *curl;
const char* gs_error;

extern X509 *g_cert;
extern EVP_PKEY *g_privateKey;

static size_t _write_curl(void *contents, size_t size, size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
PHTTP_DATA mem = (PHTTP_DATA)userp;

mem->memory = realloc(mem->memory, mem->size + realsize + 1);
if(mem->memory == NULL)
return 0;

memcpy(&(mem->memory[mem->size]), contents, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;

return realsize;
}

static CURLcode sslctx_function(CURL * curl, void * sslctx, void * parm)
{
SSL_CTX* ctx = (SSL_CTX*)sslctx;
//X509_STORE* store = SSL_CTX_get_cert_store(ctx);

//X509_STORE_add_cert(store, cert);

if(!SSL_CTX_use_certificate(ctx, g_cert))
printf("SSL_CTX_use_certificate problem\n");

if(!SSL_CTX_use_PrivateKey(ctx, g_privateKey))
printf("Use Key failed\n");

return CURLE_OK;
}

int http_init() {
curl = curl_easy_init();
if (!curl)
return GS_FAILED;

curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT, 1L);
curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE,"PEM");
curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _write_curl);
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, *sslctx_function);

return GS_OK;
}

int http_request(char* url, PHTTP_DATA data) {
curl_easy_setopt(curl, CURLOPT_WRITEDATA, data);
curl_easy_setopt(curl, CURLOPT_URL, url);

if (data->size > 0) {
free(data->memory);
data->memory = malloc(1);
if(data->memory == NULL)
return GS_OUT_OF_MEMORY;

data->size = 0;
}

//return GS_FAILED;
CURLcode res = curl_easy_perform(curl);

if(res != CURLE_OK) {
gs_error = curl_easy_strerror(res);
return GS_FAILED;
} else if (data->memory == NULL) {
return GS_OUT_OF_MEMORY;
}

return GS_OK;
}

void http_cleanup() {
curl_easy_cleanup(curl);
}

PHTTP_DATA http_create_data() {
PHTTP_DATA data = malloc(sizeof(HTTP_DATA));
if (data == NULL)
return NULL;

data->memory = malloc(1);
if(data->memory == NULL) {
free(data);
return NULL;
}
data->size = 0;

return data;
}

void http_free_data(PHTTP_DATA data) {
if (data != NULL) {
if (data->memory != NULL)
free(data->memory);

free(data);
}
}
Loading

0 comments on commit c420db5

Please sign in to comment.