GitLab doesn't like the content-disposition header generated by the MIME module.
I tried to use MIME.Message
to generate the payload for a multipart/form-data
request:
mapping(string:mixed) upload_file(string path, string data,
string|void content_type)
{
#if 0
/* For some reason GitLab does not like the following:
* { "error" : "file is missing" }
*/
MIME.Message file =
MIME.Message(data, ([
"Content-Disposition":"form-data",
"Content-Type":content_type || "application/octet-stream",
]));
file->setdisp_param("name", "file");
file->setdisp_param("filename", path);
MIME.Message msg =
MIME.Message("", ([
"Content-Type":"multipart/form-data",
"PRIVATE-TOKEN": gitlab_access_token
]), ({ file }));
string body = (((string)msg)/"\r\n\r\n")[1..] * "\r\n\r\n";
while (has_prefix(body, "\r\n")) body = body[2..];
mapping(string:string) headers = msg->headers - ([ "content-length":"" ]);
#else
/* Do it by hand. */
string boundary;
while (1) {
boundary = "----------" + String.string2hex(random_string(16));
if (!has_value(data, boundary)) break;
}
string body = sprintf("--%s\r\n"
"Content-Type: %s\r\n"
"Content-Disposition: form-data; name=%q; filename=%q\r\n"
"Content-Length: %d\r\n"
"\r\n"
"%s\r\n"
"--%s--\r\n",
boundary,
content_type || "application/octet-stream",
"file", path,
sizeof(data),
data,
boundary);
mapping(string:string) headers = ([
"content-type": "multipart/form-data; boundary=" + boundary,
"PRIVATE-TOKEN": gitlab_access_token,
]);
#endif
werror("Headers: %O\n"
"Body: %O\n",
headers, body);
Protocols.HTTP.Query q =
Protocols.HTTP.do_method("POST", api_url("uploads"), UNDEFINED,
headers, UNDEFINED, body);
string json = q->data();
return Standards.JSON.decode(json);
}
I suspect that GitLab doesn't like the disposition parameters being unquoted.