mirror of
https://github.com/dlang/phobos.git
synced 2025-05-03 00:20:26 +03:00
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:
commit
87eb83d3b8
1 changed files with 53 additions and 16 deletions
|
@ -171,8 +171,8 @@ version(unittest)
|
||||||
// Run unit test with the PHOBOS_TEST_ALLOW_NET=1 set in order to
|
// Run unit test with the PHOBOS_TEST_ALLOW_NET=1 set in order to
|
||||||
// allow net traffic
|
// allow net traffic
|
||||||
import std.stdio;
|
import std.stdio;
|
||||||
import std.c.stdlib;
|
|
||||||
import std.range;
|
import std.range;
|
||||||
|
import std.process : environment;
|
||||||
enum testUrl1 = "http://d-lang.appspot.com/testUrl1";
|
enum testUrl1 = "http://d-lang.appspot.com/testUrl1";
|
||||||
enum testUrl2 = "http://d-lang.appspot.com/testUrl2";
|
enum testUrl2 = "http://d-lang.appspot.com/testUrl2";
|
||||||
enum testUrl3 = "ftp://ftp.digitalmars.com/sieve.ds";
|
enum testUrl3 = "ftp://ftp.digitalmars.com/sieve.ds";
|
||||||
|
@ -266,8 +266,8 @@ void download(Conn = AutoProtocol)(const(char)[] url, string saveToPath, Conn co
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
if (!netAllowed()) return;
|
if (!netAllowed()) return;
|
||||||
download("ftp.digitalmars.com/sieve.ds", "/tmp/downloaded-ftp-file");
|
download("ftp.digitalmars.com/sieve.ds", getTempPath() ~ "downloaded-ftp-file");
|
||||||
download("d-lang.appspot.com/testUrl1", "/tmp/downloaded-http-file");
|
download("d-lang.appspot.com/testUrl1", getTempPath() ~ "downloaded-http-file");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Upload file from local files system using the HTTP or FTP protocol.
|
/** 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
|
unittest
|
||||||
{
|
{
|
||||||
if (!netAllowed()) return;
|
if (!netAllowed()) return;
|
||||||
// upload("/tmp/downloaded-ftp-file", "ftp.digitalmars.com/sieve.ds");
|
// upload(getTempPath() ~ "downloaded-ftp-file", "ftp.digitalmars.com/sieve.ds");
|
||||||
upload("/tmp/downloaded-http-file", "d-lang.appspot.com/testUrl2");
|
upload(getTempPath() ~ "downloaded-http-file", "d-lang.appspot.com/testUrl2");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** HTTP/FTP get content.
|
/** HTTP/FTP get content.
|
||||||
|
@ -418,11 +418,24 @@ if (is(T == char) || is(T == ubyte))
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
if (!netAllowed()) return;
|
if (!netAllowed()) return;
|
||||||
auto res = post(testUrl2, "Hello world");
|
|
||||||
assert(res == "Hello world",
|
{
|
||||||
|
string data = "Hello world";
|
||||||
|
auto res = post(testUrl2, data);
|
||||||
|
assert(res == data,
|
||||||
"put!HTTP() returns unexpected content " ~ res);
|
"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)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** HTTP/FTP put content.
|
/** HTTP/FTP put content.
|
||||||
*
|
*
|
||||||
|
@ -2398,7 +2411,7 @@ struct HTTP
|
||||||
*/
|
*/
|
||||||
@property void postData(const(void)[] data)
|
@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.
|
/** Specifying data to post when not using the onSend callback.
|
||||||
|
@ -2417,21 +2430,36 @@ struct HTTP
|
||||||
*/
|
*/
|
||||||
@property void postData(const(char)[] data)
|
@property void postData(const(char)[] data)
|
||||||
{
|
{
|
||||||
_postData(cast(void*)data.ptr, "text/plain");
|
_postData(data, "text/plain");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper for postData property
|
// 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.
|
// cannot use callback when specifying data directly so it is disabled here.
|
||||||
// here.
|
|
||||||
p.curl.clear(CurlOption.readfunction);
|
p.curl.clear(CurlOption.readfunction);
|
||||||
addRequestHeader("Content-Type", contentType);
|
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)
|
if (method == Method.undefined)
|
||||||
method = Method.post;
|
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.
|
* Set the event handler that receives incoming headers.
|
||||||
*
|
*
|
||||||
|
@ -2619,7 +2647,6 @@ struct HTTP
|
||||||
|
|
||||||
} // HTTP
|
} // HTTP
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
FTP client functionality.
|
FTP client functionality.
|
||||||
|
|
||||||
|
@ -4101,7 +4128,17 @@ private static void _spawnAsync(Conn, Unit, Terminator = void)()
|
||||||
fromTid.send(thisTid(), curlMessage(true)); // signal done
|
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/";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue