Rewrite request reading
This commit is contained in:
		
							parent
							
								
									c1599c755d
								
							
						
					
					
						commit
						0e67ffd8c4
					
				
							
								
								
									
										44
									
								
								src/header.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/header.zig
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | ||||
| const std = @import("std"); | ||||
| const mem = std.mem; | ||||
| 
 | ||||
| const RequestHeader = struct { | ||||
|     content_length: usize, | ||||
| 
 | ||||
|     /// null implies "application/vscode-jsonrpc; charset=utf-8" | ||||
|     content_type: ?[]const u8, | ||||
| 
 | ||||
|     pub fn deinit(self: @This(), allocator: *mem.Allocator) void { | ||||
|         if (self.content_type) |ct| allocator.free(ct); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| pub fn readRequestHeader(allocator: *mem.Allocator, instream: var) !RequestHeader { | ||||
|     var r = RequestHeader{ | ||||
|         .content_length = undefined, | ||||
|         .content_type = null, | ||||
|     }; | ||||
|     errdefer r.deinit(allocator); | ||||
| 
 | ||||
|     var has_content_length = false; | ||||
|     while (true) { | ||||
|         const header = try instream.readUntilDelimiterAlloc(allocator, '\n', 0x100); | ||||
|         defer allocator.free(header); | ||||
|         if (header.len == 0 or header[header.len - 1] != '\r') return error.MissingCarriageReturn; | ||||
|         if (header.len == 1) break; | ||||
| 
 | ||||
|         const header_name = header[0..mem.indexOf(u8, header, ": ") orelse return error.MissingColon]; | ||||
|         const header_value = header[header_name.len + 2..header.len-1]; | ||||
|         if (mem.eql(u8, header_name, "Content-Length")) { | ||||
|             if (header_value.len == 0) return error.MissingHeaderValue; | ||||
|             r.content_length = std.fmt.parseInt(usize, header_value, 10) catch return error.InvalidContentLength; | ||||
|             has_content_length = true; | ||||
|         } else if (mem.eql(u8, header_name, "Content-Type")) { | ||||
|             r.content_type = try mem.dupe(allocator, u8, header_value); | ||||
|         } else { | ||||
|             return error.UnknownHeader; | ||||
|         } | ||||
|     } | ||||
|     if (!has_content_length) return error.MissingContentLength; | ||||
| 
 | ||||
|     return r; | ||||
| } | ||||
							
								
								
									
										75
									
								
								src/main.zig
									
									
									
									
									
								
							
							
						
						
									
										75
									
								
								src/main.zig
									
									
									
									
									
								
							| @ -4,6 +4,7 @@ const build_options = @import("build_options"); | ||||
| const Config = @import("config.zig"); | ||||
| const DocumentStore = @import("document_store.zig"); | ||||
| const DebugAllocator = @import("debug_allocator.zig"); | ||||
| const readRequestHeader = @import("header.zig").readRequestHeader; | ||||
| const data = @import("data/" ++ build_options.data_version ++ ".zig"); | ||||
| const types = @import("types.zig"); | ||||
| const analysis = @import("analysis.zig"); | ||||
| @ -649,74 +650,18 @@ pub fn main() anyerror!void { | ||||
|     var json_parser = std.json.Parser.init(allocator, false); | ||||
|     defer json_parser.deinit(); | ||||
| 
 | ||||
|     var offset: usize = 0; | ||||
|     var bytes_read: usize = 0; | ||||
| 
 | ||||
|     var index: usize = 0; | ||||
|     var content_len: usize = 0; | ||||
| 
 | ||||
|     stdin_poll: while (true) { | ||||
|         if (offset >= 16 and std.mem.startsWith(u8, buffer.items, "Content-Length: ")) { | ||||
|             index = 16; | ||||
|             while (index <= offset + 10) : (index += 1) { | ||||
|                 const c = buffer.items[index]; | ||||
|                 if (c >= '0' and c <= '9') { | ||||
|                     content_len = content_len * 10 + (c - '0'); | ||||
|                 } else if (c == '\r' and buffer.items[index + 1] == '\n') { | ||||
|                     index += 2; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             if (buffer.items[index] == '\r') { | ||||
|                 index += 2; | ||||
|                 if (buffer.items.len < index + content_len) { | ||||
|                     try buffer.resize(index + content_len); | ||||
|                 } | ||||
| 
 | ||||
|                 body_poll: while (offset < content_len + index) { | ||||
|                     bytes_read = try stdin.readAll(buffer.items[offset .. index + content_len]); | ||||
|                     if (bytes_read == 0) { | ||||
|                         try log("0 bytes read; exiting!", .{}); | ||||
|     while (true) { | ||||
|         const headers = readRequestHeader(allocator, stdin) catch |err| { | ||||
|             try log("{}; exiting!", .{@errorName(err)}); | ||||
|             return; | ||||
|                     } | ||||
| 
 | ||||
|                     offset += bytes_read; | ||||
|                 } | ||||
| 
 | ||||
|                 try processJsonRpc(&json_parser, buffer.items[index .. index + content_len], config); | ||||
|         }; | ||||
|         defer headers.deinit(allocator); | ||||
|         const buf = try allocator.alloc(u8, headers.content_length); | ||||
|         defer allocator.free(buf); | ||||
|         try stdin.readNoEof(buf); | ||||
|         try processJsonRpc(&json_parser, buf, config); | ||||
|         json_parser.reset(); | ||||
| 
 | ||||
|                 offset = 0; | ||||
|                 content_len = 0; | ||||
|             } else { | ||||
|                 try log("\\r not found", .{}); | ||||
|             } | ||||
|         } else if (offset >= 16) { | ||||
|             try log("Offset is greater than 16!", .{}); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if (offset < 16) { | ||||
|             bytes_read = try stdin.readAll(buffer.items[offset..25]); | ||||
|         } else { | ||||
|             if (offset == buffer.items.len) { | ||||
|                 try buffer.resize(buffer.items.len * 2); | ||||
|             } | ||||
|             if (index + content_len > buffer.items.len) { | ||||
|                 bytes_read = try stdin.readAll(buffer.items[offset..buffer.items.len]); | ||||
|             } else { | ||||
|                 bytes_read = try stdin.readAll(buffer.items[offset .. index + content_len]); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (bytes_read == 0) { | ||||
|             try log("0 bytes read; exiting!", .{}); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         offset += bytes_read; | ||||
| 
 | ||||
|         if (debug_alloc) |dbg| { | ||||
|             try log("{}", .{dbg.info}); | ||||
|         } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user