Is HttpService broken?

I want to send json data from roblox to my NodeJS server hosted on my local machine. But… the data I receive on the server is garbage. Totally unreadable.


Code: (Roblox Studio)
-- main.lua
local HttpService = game:GetService('HttpService')

local config = require(script.Settings)
local dataToSend = require(script.DataToSend)

local function _connect()
	return HttpService:GetAsync(config.URL, true)
end
local function _send()
	local encoded = HttpService:JSONEncode(dataToSend.servicesData)
	print('Encoded: ',encoded)
	return HttpService:PostAsync(config.URL, encoded,
		Enum.HttpContentType.ApplicationJson, true)
end

local isConnected = false

coroutine.resume(coroutine.create(function()
	if not isConnected then
		local start = os.clock()
		local status, data = pcall(_connect)
		while not status do
			status, data = pcall(_connect)
			if os.clock() - start > config.TIMEOUT then
				error(('Cannot connect to remote host: %s'):format(data))
				return
			end
			task.wait(0.1)
		end
		isConnected = true
	
		local decoded = HttpService:JSONDecode(data)
		if decoded.isRequesting then
			if decoded.requestData and decoded.requestData == '*' then
				local status, data = pcall(_send)
				if not status then
					error('Cannot send data: ', data)
					return
				end
			end
		end
	else
		while task.wait(config.HEARTBEAT) do
			local start = os.clock()
			local status, data = pcall(_send)
			while not status do
				status, data = pcall(_send)
				if os.clock() - start > config.TIMEOUT then
					error(('Connection timed out: %s'):format(data))
					return
				end
				task.wait(0.1)
			end
			local decoded = HttpService:JSONDecode(data)
			print('Decoded: ',decoded)
		end
	end
end))

-- main.lua/Settings.lua
local module = {}

module.PORT = 2300
module.HOST = 'localhost'
module.URL = ('http://%s:%s'):format(module.HOST, module.PORT)
module.TIMEOUT = 5
module.HEARTBEAT = 10

return module

-- main.lua/dataToSend.lua
local HttpService = game:GetService('HttpService')
local module = {}

module.servicesData = {
	gameServ = require(script.Parent.ServicesData.Game)
}

return module

-- ServicesData/Game.lua
return {data1 = 'value1', data2 = 'value2'}

Output: (Roblox Studio)

Encoded: {"gameServ":{"data1": "value1", "data2": "value2"}}

Code: (NodeJS Server)
import * as http from 'http'
const server = http.createServer()
server.on('request', (req: http.IncomingMessage, res: http.ServerResponse) => {
    if(req.headers['user-agent'] && req.headers['user-agent'].startsWith('RobloxStudio/')){
        if(req.method == 'POST') {
            let rawData = ''
            req.on('data', (chunk: any) => {
                console.log(chunk, chunk.toString('utf-8'))
                rawData += chunk;
            })
            
            req.on('end', () => {
                try {
                    const parsedData = JSON.parse(rawData)
                    console.log(parsedData)
                } catch (err) {
                    console.error(err) // <-- catched error: Unexpected token
                }finally {
                    res.writeHead(200, 'OK', {'Content-Type': 'application/json'})
                    res.end()
                }
            })
        }
    }
})

Output: (NodeJS Server)

<Buffer 1f 8b 08 00 00 00 00 00 00 ff 75 54 4d 73 da 30 14
fc 2b 8c ce 1c c0 0c 81 70 aa 0b 35 75 86 16 a6 4e 93 b3
90 1f b6 3a ca 13 23 3d 27 c3 64 f2 df 2b ... 525 more bytes>
u�▬�N���▼�:�‼#=�d��+Z�x,���fA▼�&♣^MѺ�ZgwՉ郖
&��d9��♣▼▼�☺WO>r♣
SyntaxError: Unexpected token ▼ in JSON at position 0

You are compressing your data in roblox (the final true part of PostAsync) but it would seem your NodeJS server is not decompressing the stream.

2 Likes

Can you log “rawData”, what does it print?

It prints these Unicode chars under the Buffer line

Then try the following:
JSON.parse(rawData.toString("utf8"))

Edit: I do find it weird that it still is a buffer even if you had converted it to a string.

Oh lol xD
I completely forgot about it. I’ll change my code a little bit and decompress it first

Tried already. If you do “toString” then Unicode chars appears

but don’t you want it to be unicode characters? Like “{‘hello’: true}” instead of 23,32...

I want it to be json string. Not some random Unicode chars.

So what you mean by Unicode characters is the byte code? (the byte code is the 1f,8b...)

The characters below the byte line. Right above the error message

Yup that was the case. Tyvm <3