initial commit on code to work around 17015. Sourced from std lib
This commit is contained in:
		
							parent
							
								
									55f662f5d7
								
							
						
					
					
						commit
						d50503a2f8
					
				
					 1 changed files with 157 additions and 0 deletions
				
			
		
							
								
								
									
										157
									
								
								src/http_client_17015_issue.zig
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								src/http_client_17015_issue.zig
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,157 @@ | |||
| const std = @import("../std.zig"); | ||||
| const Uri = std.http.Uri; | ||||
| 
 | ||||
| pub const StartError = std.http.Connection.WriteError || error{ InvalidContentLength, UnsupportedTransferEncoding }; | ||||
| 
 | ||||
| /////////////////////////////////////////////////////////////////////////// | ||||
| /// This function imported from: | ||||
| /// https://github.com/ziglang/zig/blob/0.11.0/lib/std/http/Client.zig#L538-L636 | ||||
| /// | ||||
| /// The first commit of this file will be unchanged from 0.11.0 to more | ||||
| /// clearly indicate changes moving forward. The plan is to change | ||||
| /// only the two w.print lines for req.uri 16 and 18 lines down from this comment | ||||
| /////////////////////////////////////////////////////////////////////////// | ||||
| /// Send the request to the server. | ||||
| pub fn start(req: *std.http.Client.Request) StartError!void { | ||||
|     var buffered = std.io.bufferedWriter(req.connection.?.data.writer()); | ||||
|     const w = buffered.writer(); | ||||
| 
 | ||||
|     try w.writeAll(@tagName(req.method)); | ||||
|     try w.writeByte(' '); | ||||
| 
 | ||||
|     if (req.method == .CONNECT) { | ||||
|         try w.writeAll(req.uri.host.?); | ||||
|         try w.writeByte(':'); | ||||
|         try w.print("{}", .{req.uri.port.?}); | ||||
|     } else if (req.connection.?.data.proxied) { | ||||
|         // proxied connections require the full uri | ||||
|         try w.print("{+/}", .{req.uri}); | ||||
|     } else { | ||||
|         try w.print("{/}", .{req.uri}); | ||||
|     } | ||||
| 
 | ||||
|     try w.writeByte(' '); | ||||
|     try w.writeAll(@tagName(req.version)); | ||||
|     try w.writeAll("\r\n"); | ||||
| 
 | ||||
|     if (!req.headers.contains("host")) { | ||||
|         try w.writeAll("Host: "); | ||||
|         try w.writeAll(req.uri.host.?); | ||||
|         try w.writeAll("\r\n"); | ||||
|     } | ||||
| 
 | ||||
|     if (!req.headers.contains("user-agent")) { | ||||
|         try w.writeAll("User-Agent: zig/"); | ||||
|         try w.writeAll(@import("builtin").zig_version_string); | ||||
|         try w.writeAll(" (std.http)\r\n"); | ||||
|     } | ||||
| 
 | ||||
|     if (!req.headers.contains("connection")) { | ||||
|         try w.writeAll("Connection: keep-alive\r\n"); | ||||
|     } | ||||
| 
 | ||||
|     if (!req.headers.contains("accept-encoding")) { | ||||
|         try w.writeAll("Accept-Encoding: gzip, deflate, zstd\r\n"); | ||||
|     } | ||||
| 
 | ||||
|     if (!req.headers.contains("te")) { | ||||
|         try w.writeAll("TE: gzip, deflate, trailers\r\n"); | ||||
|     } | ||||
| 
 | ||||
|     const has_transfer_encoding = req.headers.contains("transfer-encoding"); | ||||
|     const has_content_length = req.headers.contains("content-length"); | ||||
| 
 | ||||
|     if (!has_transfer_encoding and !has_content_length) { | ||||
|         switch (req.transfer_encoding) { | ||||
|             .chunked => try w.writeAll("Transfer-Encoding: chunked\r\n"), | ||||
|             .content_length => |content_length| try w.print("Content-Length: {d}\r\n", .{content_length}), | ||||
|             .none => {}, | ||||
|         } | ||||
|     } else { | ||||
|         if (has_content_length) { | ||||
|             const content_length = std.fmt.parseInt(u64, req.headers.getFirstValue("content-length").?, 10) catch return error.InvalidContentLength; | ||||
| 
 | ||||
|             req.transfer_encoding = .{ .content_length = content_length }; | ||||
|         } else if (has_transfer_encoding) { | ||||
|             const transfer_encoding = req.headers.getFirstValue("transfer-encoding").?; | ||||
|             if (std.mem.eql(u8, transfer_encoding, "chunked")) { | ||||
|                 req.transfer_encoding = .chunked; | ||||
|             } else { | ||||
|                 return error.UnsupportedTransferEncoding; | ||||
|             } | ||||
|         } else { | ||||
|             req.transfer_encoding = .none; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     try w.print("{}", .{req.headers}); | ||||
| 
 | ||||
|     try w.writeAll("\r\n"); | ||||
| 
 | ||||
|     try buffered.flush(); | ||||
| } | ||||
| 
 | ||||
| /////////////////////////////////////////////////////////////////////////// | ||||
| /// This function imported from: | ||||
| /// https://github.com/ziglang/zig/blob/0.11.0/lib/std/Uri.zig#L209-L264 | ||||
| /// | ||||
| /// The first commit of this file will be unchanged from 0.11.0 to more | ||||
| /// clearly indicate changes moving forward. The plan is to change | ||||
| /// only the writeEscapedPath call 42 lines down from this comment | ||||
| /////////////////////////////////////////////////////////////////////////// | ||||
| pub fn format( | ||||
|     uri: Uri, | ||||
|     comptime fmt: []const u8, | ||||
|     options: std.fmt.FormatOptions, | ||||
|     writer: anytype, | ||||
| ) @TypeOf(writer).Error!void { | ||||
|     _ = options; | ||||
| 
 | ||||
|     const needs_absolute = comptime std.mem.indexOf(u8, fmt, "+") != null; | ||||
|     const needs_path = comptime std.mem.indexOf(u8, fmt, "/") != null or fmt.len == 0; | ||||
|     const needs_fragment = comptime std.mem.indexOf(u8, fmt, "#") != null; | ||||
| 
 | ||||
|     if (needs_absolute) { | ||||
|         try writer.writeAll(uri.scheme); | ||||
|         try writer.writeAll(":"); | ||||
|         if (uri.host) |host| { | ||||
|             try writer.writeAll("//"); | ||||
| 
 | ||||
|             if (uri.user) |user| { | ||||
|                 try writer.writeAll(user); | ||||
|                 if (uri.password) |password| { | ||||
|                     try writer.writeAll(":"); | ||||
|                     try writer.writeAll(password); | ||||
|                 } | ||||
|                 try writer.writeAll("@"); | ||||
|             } | ||||
| 
 | ||||
|             try writer.writeAll(host); | ||||
| 
 | ||||
|             if (uri.port) |port| { | ||||
|                 try writer.writeAll(":"); | ||||
|                 try std.fmt.formatInt(port, 10, .lower, .{}, writer); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (needs_path) { | ||||
|         if (uri.path.len == 0) { | ||||
|             try writer.writeAll("/"); | ||||
|         } else { | ||||
|             try Uri.writeEscapedPath(writer, uri.path); | ||||
|         } | ||||
| 
 | ||||
|         if (uri.query) |q| { | ||||
|             try writer.writeAll("?"); | ||||
|             try Uri.writeEscapedQuery(writer, q); | ||||
|         } | ||||
| 
 | ||||
|         if (needs_fragment) { | ||||
|             if (uri.fragment) |f| { | ||||
|                 try writer.writeAll("#"); | ||||
|                 try Uri.writeEscapedQuery(writer, f); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Loading…
	
	Add table
		
		Reference in a new issue