diff options
| author | Florian Fischer <florian.fischer@muhq.space> | 2025-09-06 11:38:55 +0200 |
|---|---|---|
| committer | Florian Fischer <florian.fischer@muhq.space> | 2025-09-06 11:38:55 +0200 |
| commit | 8d505da65ad325732fa35abcf4032c9b1883c0af (patch) | |
| tree | bc05cd8516f5b1d8183cf59483fa311bc6806be1 | |
| parent | b6ecd9ce3012d6a6322fd013f5fad5e5f54856bb (diff) | |
| download | vis-lspc-8d505da65ad325732fa35abcf4032c9b1883c0af.tar.gz vis-lspc-8d505da65ad325732fa35abcf4032c9b1883c0af.zip | |
parse LSP messages containing a Content-Type header
| -rw-r--r-- | parser.lua | 5 | ||||
| -rwxr-xr-x | parser_test.lua | 16 |
2 files changed, 19 insertions, 2 deletions
@@ -23,7 +23,7 @@ function Parser:add(data) -- we have not seen a complete header in data yet if not self.exp_len then -- search for the end of a header - -- LSP message format: 'header\r\n\r\nbody' + -- LSP message format: header\r\n(header\r\n)?\r\nbody' local header_end, content_start = self.data:find('\r\n\r\n') -- header is not complete yet -> save data and wait for more @@ -35,7 +35,8 @@ function Parser:add(data) local header = self.data:sub(1, header_end) -- extract content length from the header - self.exp_len = tonumber(header:match('%d+')) + local length = header:match('Content%-Length: %d+') + self.exp_len = tonumber(length:match('%d+')) if not self.exp_len then return 'invalid header in data: ' .. self.data end diff --git a/parser_test.lua b/parser_test.lua index 28f3d0f..1b5e4b1 100755 --- a/parser_test.lua +++ b/parser_test.lua @@ -8,6 +8,22 @@ end local lunatest = require('lunatest') +-- Actual LSP message in the wild. +function test_msg_with_content_type() -- luacheck: ignore 111 + local msg = 'Content-Type: application/vscode-jsonrpc; charset=utf8\r\n' .. + 'Content-Length: 1996\r\n\r\n' .. + [[{"jsonrpc":"2.0","id":0,"result":{"capabilities":{"textDocumentSync":1,"completionProvider":{"triggerCharacters":[":",">","$","[","@","(","'","\"","\\"],"resolveProvider":true},"hoverProvider":true,"signatureHelpProvider":{"triggerCharacters":["(",",","@"]},"definitionProvider":true,"typeDefinitionProvider":true,"implementationProvider":true,"referencesProvider":true,"documentHighlightProvider":true,"documentSymbolProvider":true,"codeActionProvider":{"codeActionKinds":["refactor.class.simplify","quickfix.import_class","quickfix.promote_constructor","quickfix.remove_unused_imports","quickfix.promote_constructor_public","quickfix.complete_constructor","quickfix.fill.object","quickfix.here_doc_provider","quickfix.complete_constructor_public","refactor.extract.constant","refactor.extract.method","quickfix.generate_member","quickfix.create_class","quickfix.add_missing_return_types","quickfix.add_missing_params","quickfix.add_missing_docblocks_return","quickfix.fix_namespace_class_name","refactor.extract.expression","quickfix.fill.matchArms","quickfix.correct_variable_name","quickfix.create_unresolable_class","quickfix.generate_decorator","refactor","quickfix.generate_mutators","quickfix.add_missing_properties","quickfix.implement_contracts","quickfix.add_missing_class_generic","quickfix.generate_accessors","quickfix.override_method"]},"workspaceSymbolProvider":true,"renameProvider":{"prepareProvider":true},"selectionRangeProvider":true,"executeCommandProvider":{"commands":["name_import","transform","create_class","generate_member","extract_method","replace_qualifier_with_import","extract_constant","generate_accessors","generate_mutators","import_all_unresolved_names","extract_expression","generate_decorator","override_method"]},"inlineValueProvider":true,"workspace":{"fileOperations":{"willRename":{"filters":[{"pattern":{"glob":"**\/*.php"}}]}}},"experimental":{"xevaluatableExpressionProvider":true}},"serverInfo":{"name":"phpactor\/phpactor","version":"dev-master"}}}]] -- luacheck: ignore 631 + + local p = parser.new() + local err = p:add(msg) + lunatest.assert_nil(err) + + local msgs = p:get_msgs() + lunatest.assert_table(msgs) + lunatest.assert_len(1, msgs) + lunatest.assert_not_nil(msgs[1]) +end + function test_complete_msg() -- luacheck: ignore 111 local msg = build_msg('foo') local p = parser.new() |
