Merge pull request #800 from CyberShadow/std-net-curl-binary-post

std.net.curl: Do not assume POST data is null-terminated string
This commit is contained in:
Andrei Alexandrescu 2012-09-25 22:27:11 -07:00
commit 87eb83d3b8

View file

@ -171,8 +171,8 @@ version(unittest)
// Run unit test with the PHOBOS_TEST_ALLOW_NET=1 set in order to
// allow net traffic
import std.stdio;
import std.c.stdlib;
import std.range;
import std.process : environment;
enum testUrl1 = "http://d-lang.appspot.com/testUrl1";
enum testUrl2 = "http://d-lang.appspot.com/testUrl2";
enum testUrl3 = "ftp://ftp.digitalmars.com/sieve.ds";
@ -266,8 +266,8 @@ void download(Conn = AutoProtocol)(const(char)[] url, string saveToPath, Conn co
unittest
{
if (!netAllowed()) return;
download("ftp.digitalmars.com/sieve.ds", "/tmp/downloaded-ftp-file");
download("d-lang.appspot.com/testUrl1", "/tmp/downloaded-http-file");
download("ftp.digitalmars.com/sieve.ds", getTempPath() ~ "downloaded-ftp-file");
download("d-lang.appspot.com/testUrl1", getTempPath() ~ "downloaded-http-file");
}
/** Upload file from local files system using the HTTP or FTP protocol.
@ -322,8 +322,8 @@ void upload(Conn = AutoProtocol)(string loadFromPath, const(char)[] url, Conn co
unittest
{
if (!netAllowed()) return;
// upload("/tmp/downloaded-ftp-file", "ftp.digitalmars.com/sieve.ds");
upload("/tmp/downloaded-http-file", "d-lang.appspot.com/testUrl2");
// upload(getTempPath() ~ "downloaded-ftp-file", "ftp.digitalmars.com/sieve.ds");
upload(getTempPath() ~ "downloaded-http-file", "d-lang.appspot.com/testUrl2");
}
/** HTTP/FTP get content.
@ -418,9 +418,22 @@ if (is(T == char) || is(T == ubyte))
unittest
{
if (!netAllowed()) return;
auto res = post(testUrl2, "Hello world");
assert(res == "Hello world",
"put!HTTP() returns unexpected content " ~ res);
{
string data = "Hello world";
auto res = post(testUrl2, data);
assert(res == data,
"put!HTTP() returns unexpected content " ~ res);
}
{
ubyte[] data;
foreach (n; 0..256)
data ~= cast(ubyte)n;
auto res = post!ubyte(testUrl2, data);
assert(res == data,
"put!HTTP() with binary data returns unexpected content (" ~ text(res.length) ~ " bytes)");
}
}
@ -2398,7 +2411,7 @@ struct HTTP
*/
@property void postData(const(void)[] data)
{
_postData(cast(void*)data.ptr, "application/octet-stream");
_postData(data, "application/octet-stream");
}
/** Specifying data to post when not using the onSend callback.
@ -2417,21 +2430,36 @@ struct HTTP
*/
@property void postData(const(char)[] data)
{
_postData(cast(void*)data.ptr, "text/plain");
_postData(data, "text/plain");
}
// Helper for postData property
private void _postData(void* data, string contentType)
private void _postData(const(void)[] data, string contentType)
{
// cannot use callback when specifying data directly so it is disabled here.
// here.
p.curl.clear(CurlOption.readfunction);
addRequestHeader("Content-Type", contentType);
p.curl.set(CurlOption.postfields, data);
p.curl.set(CurlOption.postfields, cast(void*)data.ptr);
p.curl.set(CurlOption.postfieldsize, data.length);
if (method == Method.undefined)
method = Method.post;
}
unittest
{
if (!netAllowed()) return;
ubyte[] data;
foreach (n; 0..256)
data ~= cast(ubyte)n;
auto http = HTTP(testUrl2);
http.postData = data;
ubyte[] result;
http.onReceive = (ubyte[] data) { result ~= data; return data.length; };
http.perform();
assert(data == result,
"HTTP POST with binary data returns unexpected content (" ~ text(result.length) ~ " bytes)");
}
/**
* Set the event handler that receives incoming headers.
*
@ -2619,7 +2647,6 @@ struct HTTP
} // HTTP
/**
FTP client functionality.
@ -4101,7 +4128,17 @@ private static void _spawnAsync(Conn, Unit, Terminator = void)()
fromTid.send(thisTid(), curlMessage(true)); // signal done
}
version (unittest) private auto netAllowed()
version (unittest)
{
return getenv("PHOBOS_TEST_ALLOW_NET") != null;
private auto netAllowed()
{
return environment.get("PHOBOS_TEST_ALLOW_NET") != null;
}
private string getTempPath()
{
version (Windows)
return environment["TEMP"] ~ `\`;
else
return "/tmp/";
}
}