Alright I was out eating and took a break from this lmao but now I have this:
When I upload a file I first select it and then upload. More than one file is at least via gui not possible.
Working example performed by the browser
The request payload then looks like this:
-----------------------------273344254425326470862221127403
Content-Disposition: form-data; name="fileToUpload"; filename="stab.h"
Content-Type: text/x-chdr
#ifndef __GNU_STAB__
/* Indicate the GNU stab.h is in use. */
#define __GNU_STAB__
#define __define_stab(NAME, CODE, STRING) NAME=CODE,
enum __stab_debug_code
{
#include <bits/stab.def>
LAST_UNUSED_STAB_CODE
};
#undef __define_stab
#endif /* __GNU_STAB_ */
-----------------------------273344254425326470862221127403
Content-Disposition: form-data; name="submit"
Upload File
-----------------------------273344254425326470862221127403--
The file here is just something I found laying around.
The headers are
POST /upload.php HTTP/2
Host: www.example.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br, zstd
Content-Type: multipart/form-data; boundary=---------------------------273344254425326470862221127403
Content-Length: 613
Origin: www.example.com
DNT: 1
Connection: keep-alive
Referer: https://example.com/upload.php
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Priority: u=0, i
My code
const std = @import("std");
test {
const allocator = std.testing.allocator;
const filename = "file1.txt";
const file =
\\some
\\test
\\file
\\
;
var client = std.http.Client{ .allocator = allocator };
defer client.deinit();
const uri = try std.Uri.parse("https://example.com/upload.php");
var buf: [1024 * 1024]u8 = undefined;
var req = try client.open(.POST, uri, .{ .server_header_buffer = &buf });
defer req.deinit();
const boundary = "-----------------------------1760513608948131895337362114";
const content = std.fmt.comptimePrint(
\\{[boundary]s}
\\Content-Disposition: form-data; name="fileToUpload"; filename="{[filename]s}"
\\Content-Type: text/x-chdr
\\
\\{[file]s}
\\{[boundary]s}
\\Content-Disposition: form-data; name="submit"
\\
\\Upload File
\\{[boundary]s}--
, .{ .boundary = boundary, .filename = filename, .file = file });
std.debug.print("{s}\n", .{content});
req.headers.content_type = .{ .override = "multipart/form-data; boundary=" ++ boundary };
req.transfer_encoding = .{ .content_length = content.len };
try req.send();
try req.writeAll(content);
try req.finish();
try req.wait();
try std.testing.expectEqual(.ok, req.response.status);
const mssg = try req.reader().readAllAlloc(allocator, std.math.maxInt(usize));
defer allocator.free(mssg);
const out_file = try std.fs.cwd().createFile("index.html", .{});
defer out_file.close();
try out_file.writeAll(mssg);
}
My program receives the http code 200 (== .ok), however index.html
is displaying the site with a notification saying that no files were uploaded.