Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTPResponse.Data throws exception "Invalid JSON" #63

Open
roby2014 opened this issue Sep 16, 2021 · 10 comments
Open

HTTPResponse.Data throws exception "Invalid JSON" #63

roby2014 opened this issue Sep 16, 2021 · 10 comments

Comments

@roby2014
Copy link

roby2014 commented Sep 16, 2021

Hello.
Im trying something and I cannot understand if its my code or the extension that is not working as it should.
Im doing an API request where it should return me some JSON data. The problem is, Im getting some errors:

L 09/16/2021 - 12:41:21: [SM] Exception reported: Invalid JSON in line 1, column 86: ':' expected near end of file
L 09/16/2021 - 12:41:21: [SM] Blaming: csgopanel_gametracker.smx
L 09/16/2021 - 12:41:21: [SM] Call stack trace:
L 09/16/2021 - 12:41:21: [SM]   [0] HTTPResponse.Data.get
L 09/16/2021 - 12:41:21: [SM]   [1] Line 47, h:\coding\csgopanel_sm\scripting\include\gametracker/httpcallbacks.sp::httpcallback_getgametracker 

(but sometimes error message is different) :

L 09/16/2021 - 13:59:14: [SM] Exception reported: Invalid JSON in line 1, column 85: premature end of input near '"points' 
L 09/16/2021 - 13:59:14: [SM] Blaming: csgopanel_gametracker.smx 
L 09/16/2021 - 13:59:15: [SM] Call stack trace: 
L 09/16/2021 - 13:59:15: [SM]   [0] HTTPResponse.Data.get
L 09/16/2021 - 13:59:15: [SM]   [1] Line 47, h:\coding\csgopanel_sm\scripting\include\gametracker/httpcallbacks.sp::httpcallback_getgametracker     

This is my code (where the exception occurs).

public void httpcallback_getgametracker(HTTPResponse response, any userid, const char[] error) {
    int client = GetClientOfUserId(userid);
    if (!(IsClientConnected(client) && !IsFakeClient(client) && !IsClientSourceTV(client))) {
        return;
    }

    if (response.Status != HTTPStatus_OK && response.Status != HTTPStatus_Created) {
        LogError("\nError on request \" get/gametracker \" (%i)\nError: %s", response.Status, error);
        return;
    }

    JSONObject user_data = view_as<JSONObject>(response.Data); // ERROR HERE
// ...
}

I do not understand the error because, testing this endpoint on a software like Postman, it gives me valid JSON
Example:

Setup:

  • ripext version: 1.3.1 (latest)
  • game: css
  • sourcemod version: 1.10.0.6510
  • server os: windows

Thanks in advance.

@CrazyHackGUT
Copy link
Contributor

Show the code and full endpoint. It looks like you incorrect build the link.
You can check manually web server logs.

@roby2014
Copy link
Author

roby2014 commented Sep 26, 2021

@CrazyHackGUT Hello, thanks for answering.

Full code here, with screenshots also with the JSON sent to the endpoint.

void get_player_info(int client) {
	GetClientName(client, g_players[client].name, sizeof(CSGOPanelUser::name));
	GetClientAuthId(client, AuthId_SteamID64, g_players[client].steam_id, sizeof(CSGOPanelUser::steam_id));

	JSONObject json = new JSONObject();
	json.SetString("token", TOKEN);
	json.SetInt("server_id", SERVERID);
	json.SetString("steamid", g_players[client].steam_id);

        if (DEBUG) {
		char debugjson[MAX_DEBUG_LENGTH];
		json.ToString(debugjson, sizeof(debugjson), JSON_INDENT(5));
		LogMessage("\n@ get_player_info @ sending api request to \"%s\":\n%s\n", "https://api.csgopanel.com/get/gametracker", debugjson);
    }
	
	HTTPRequest req = new HTTPRequest("https://api.csgopanel.com/get/gametracker");
	req.SetHeader("Content-Type", "application/json");
	req.Post(json, httpcallback_getgametracker, GetClientUserId(client));

	delete json;
}

public void httpcallback_getgametracker(HTTPResponse response, any userid, const char[] error) {
    int client = GetClientOfUserId(userid);
    if (!(IsClientConnected(client) && !IsFakeClient(client) && !IsClientSourceTV(client))) {
        return;
    }

    if (response.Status != HTTPStatus_OK && response.Status != HTTPStatus_Created) {
        LogError("\nError on request \" get/gametracker \" (%i)\nError: %s", response.Status, error);
        return;
    }

    LogMessage("\n client exists... lets get his data %i \n", response.Status);

    JSONObject user_data = view_as<JSONObject>(response.Data); // ERROR, function stops here.

    if (DEBUG) {
		char debugjson[MAX_DEBUG_LENGTH];
		user_data.ToString(debugjson, sizeof(debugjson), JSON_INDENT(5));
		LogMessage("\n@ httpcallback_getgametracker @ received player data:\n%s\n", debugjson);
    }
}

json debug:

@roby2014
Copy link
Author

roby2014 commented Sep 26, 2021

Also, as you can see, using another API testing tool like Insomnia and sending the same JSON to the endpoint as the plugin, it gives me a valid JSON response...

@ErikMinekus
Copy link
Owner

Could you try the debug build posted here, and post the output from the server console?

@roby2014
Copy link
Author

roby2014 commented Nov 6, 2021

Hello @ErikMinekus , yes sure.
I have attached a .txt file with the console output, and also there is the plugin source code:

public void OnClientAuthorized(int client, const char[] auth) {
	if (!IsFakeClient(client)) {
		get_player_info(client);
	}
}

void get_player_info(int client) {
    char name[64];
    char steam_id[64];
	GetClientName(client, name, sizeof(name));
	GetClientAuthId(client, AuthId_SteamID64, steam_id, sizeof(steam_id));

	JSONObject json = new JSONObject();
	json.SetString("token", TOKEN);
	json.SetInt("server_id", SERVERID);
	json.SetString("steamid", steam_id);

    if (DEBUG) {
		char debugjson[MAX_DEBUG_LENGTH];
		json.ToString(debugjson, sizeof(debugjson), JSON_INDENT(5));
		LogMessage("\n@ get_player_info @ sending api request to \"%s\":\n%s\n", "https://api.csgopanel.com/get/gametracker", debugjson);
    }
	
	HTTPRequest req = new HTTPRequest("https://api.csgopanel.com/get/gametracker");
	req.SetHeader("Content-Type", "application/json");
	req.Post(json, httpcallback_getgametracker, GetClientUserId(client));

	delete json;
}

public void httpcallback_getgametracker(HTTPResponse response, any userid, const char[] error) {
    int client = GetClientOfUserId(userid);
    if (response.Status != HTTPStatus_OK && response.Status != HTTPStatus_Created) {
        LogError("\nError on request \" get/gametracker \" (%i)\nError: %s", response.Status, error);
        return;
    }

    JSONObject user_data = view_as<JSONObject>(response.Data); // CRASH, function stops here.

    if (DEBUG) {
		char debugjson[MAX_DEBUG_LENGTH];
		user_data.ToString(debugjson, sizeof(debugjson), JSON_INDENT(5));
		LogMessage("\n@ httpcallback_getgametracker @ received player data:\n%s\n", debugjson);
    }
}

errors.txt

@ESK0
Copy link

ESK0 commented Nov 9, 2021

Hi @ErikMinekus,

we do have a similar issue (https://github.com/ESK0/eItems/blob/main/scripting/files/parse.sp#L43)

basically we have found out that this happen on Windows only and only if the endpoint is https, http works just fine.

L 11/09/2021 - 05:17:57: [SM] Exception reported: Invalid JSON in line 1, column 2014: unexpected token near end of file
L 11/09/2021 - 05:17:57: [SM] Blaming: eitems.smx
L 11/09/2021 - 05:17:57: [SM] Call stack trace:
L 11/09/2021 - 05:17:57: [SM]   [0] HTTPResponse.Data.get
L 11/09/2021 - 05:17:57: [SM]   [1] Line 43, files\parse.sp::ParseItemsDownloaded

=== Info: h2_process_pending_input: 2715724417014431744 bytes left in connection buffer

=== Info: http2_recv returns AGAIN for stream 1

=== Info: http2_recv: easy 0x25b77d90 (stream 1) win 33543474/33543474

=== Info: Use data left in connection buffer, nread=0

@ErikMinekus
Copy link
Owner

Yes, it’s an issue with HTTP/2 on Windows. HTTP/2 is only attempted over HTTPS.

@ESK0
Copy link

ESK0 commented Nov 9, 2021

Yes, it’s an issue with HTTP/2 on Windows. HTTP/2 is only attempted over HTTPS.

Is there a workaround?

@Wend4r
Copy link
Contributor

Wend4r commented Nov 9, 2021

Yes, it’s an issue with HTTP/2 on Windows. HTTP/2 is only attempted over HTTPS.

Is there a workaround?

Use SteamWorks extension and convert body to JSON via JSONArray.FromString/JSONObject.FromString

@ESK0
Copy link

ESK0 commented Nov 9, 2021

Yes, it’s an issue with HTTP/2 on Windows. HTTP/2 is only attempted over HTTPS.

Is there a workaround?

Use SteamWorks extension and convert body to JSON via JSONArray.FromString/JSONObject.FromString

This can be inconvenient for many people (install another extension)... but probably the fastest solution at the moment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants