Skip to content

Commit

Permalink
Merge pull request #4259 from GilesBathgate/master
Browse files Browse the repository at this point in the history
Implement post overload in std.net.curl
  • Loading branch information
DmitryOlshansky committed May 6, 2016
2 parents d0ef84f + 9185ddd commit ce12cc4
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 16 deletions.
57 changes: 41 additions & 16 deletions std/net/curl.d
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,11 @@ Example:
---
import std.net.curl, std.stdio;
// Return a char[] containing the content specified by an URL
// Return a char[] containing the content specified by a URL
auto content = get("dlang.org");
// Post data and return a char[] containing the content specified by an URL
auto content = post("mydomain.com/here.cgi", "post data");
// Post data and return a char[] containing the content specified by a URL
auto content = post("mydomain.com/here.cgi", ["name1" : "value1", "name2" : "value2"]);
// Get content of file from ftp server
auto content = get("ftp.digitalmars.com/sieve.ds");
Expand Down Expand Up @@ -566,22 +566,26 @@ unittest
/** HTTP post content.
*
* Params:
* url = resource to post to
* postData = data to send as the body of the request. An array
* of an arbitrary type is accepted and will be cast to ubyte[]
* before sending it.
* conn = HTTP connection to use
* url = resource to post to
* postDict = data to send as the body of the request. An associative array
* of $(D string) is accepted and will be encoded using
* www-form-urlencoding
* postData = data to send as the body of the request. An array
* of an arbitrary type is accepted and will be cast to ubyte[]
* before sending it.
* conn = HTTP connection to use
* T = The template parameter $(D T) specifies the type to return. Possible values
* are $(D char) and $(D ubyte) to return $(D char[]) or $(D ubyte[]). If asking
* for $(D char), content will be converted from the connection character set
* (specified in HTTP response headers or FTP connection properties, both ISO-8859-1
* by default) to UTF-8.
*
* The template parameter $(D T) specifies the type to return. Possible values
* are $(D char) and $(D ubyte) to return $(D char[]) or $(D ubyte[]). If asking
* for $(D char), content will be converted from the connection character set
* (specified in HTTP response headers or FTP connection properties, both ISO-8859-1
* by default) to UTF-8.
*
* Example:
* Examples:
* ----
* import std.net.curl;
* auto content = post("d-lang.appspot.com/testUrl2", [1,2,3,4]);
*
* auto content1 = post("d-lang.appspot.com/testUrl2", ["name1" : "value1", "name2" : "value2"]);
* auto content2 = post("d-lang.appspot.com/testUrl2", [1,2,3,4]);
* ----
*
* Returns:
Expand Down Expand Up @@ -627,6 +631,27 @@ unittest
assert(res == cast(ubyte[])[17, 27, 35, 41]);
}

/// ditto
T[] post(T = char)(const(char)[] url, string[string] postDict, HTTP conn = HTTP())
if (is(T == char) || is(T == ubyte))
{
import std.uri : urlEncode;

return post(url, urlEncode(postDict), conn);
}

unittest
{
foreach (host; [testServer.addr, "http://" ~ testServer.addr])
{
testServer.handle((s) {
auto req = s.recvReq!char;
s.send(httpOK(req.bdy));
});
auto res = post(host ~ "/path", ["name1" : "value1", "name2" : "value2"]);
assert(res == "name1=value1&name2=value2");
}
}

/** HTTP/FTP put content.
*
Expand Down
38 changes: 38 additions & 0 deletions std/uri.d
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,44 @@ string encodeComponent(Char)(in Char[] uriComponent) if (isSomeChar!Char)
return URI_Encode(s, URI_Alpha | URI_Digit | URI_Mark);
}

/* Encode associative array using www-form-urlencoding
*
* Params:
* values = an associative array containing the values to be encoded.
*
* Returns:
* A string encoded using www-form-urlencoding.
*/
package string urlEncode(in string[string] values)
{
if (values.length == 0)
return "";

import std.array : Appender;
import std.format : formattedWrite;

Appender!string enc;
enc.reserve(values.length * 128);

bool first = true;
foreach (k, v; values)
{
if (!first)
enc.put('&');
formattedWrite(enc, "%s=%s", encodeComponent(k), encodeComponent(v));
first = false;
}
return enc.data;
}

unittest
{
string[string] a;
assert(urlEncode(a) == "");
assert(urlEncode(["name1" : "value1"]) == "name1=value1");
assert(urlEncode(["name1" : "value1", "name2" : "value2"]) == "name1=value1&name2=value2");
}

/***************************
* Does string s[] start with a URL?
* Returns:
Expand Down

0 comments on commit ce12cc4

Please sign in to comment.