123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- /**
- Convenience functions for working with web forms.
- Copyright: © 2012-2015 Sönke Ludwig
- License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file.
- Authors: Sönke Ludwig, Jan Krüger
- */
- module vibe.http.form;
- public import vibe.inet.webform;
- import vibe.http.client : HTTPClientRequest; // for writeFormBody
- import vibe.http.server;
- import std.array;
- import std.conv;
- import std.range;
- import std.string;
- import std.typecons : isTuple;
- /**
- Encodes the given dictionary as URL encoded form data.
- */
- void writeFormData(R)(R dst, in string[string] data)
- if (isOutputRange!(R, char))
- {
- import vibe.textfilter.urlencode;
- bool first = true;
- foreach (k, v; data) {
- if (first) first = false;
- else dst.put("&");
- filterURLEncode(dst, k);
- dst.put("=");
- filterURLEncode(dst, v);
- }
- }
- ///
- unittest {
- import std.array;
- import vibe.core.log;
- import vibe.http.form;
- void test()
- {
- auto dst = appender!string();
- dst.writeFormData(["field1": "value1", "field2": "value2"]);
- logInfo("Form data: %s", dst.data);
- }
- }
- /**
- Encodes the given ranges of `Tuple!(string, string)` as URL encoded form data
- */
- void writeFormData(R, PairRange)(R dst, PairRange pr)
- if (isOutputRange!(R, char) && isTuple!(ElementType!PairRange) && ElementType!PairRange.length == 2)
- {
- import vibe.textfilter.urlencode;
- if(pr.empty) return;
- auto fst = pr.front;
- pr.popFront();
- filterURLEncode(dst, fst[0]);
- dst.put("=");
- filterURLEncode(dst, fst[1]);
- foreach (pair; pr) {
- dst.put("&");
- filterURLEncode(dst, pair[0]);
- dst.put("=");
- filterURLEncode(dst, pair[1]);
- }
- }
- /**
- Writes a `vibe.http.client.HTTPClientRequest` body as URL encoded form data.
- */
- void writeFormBody(HTTPClientRequest req, in string[string] form)
- {
- import vibe.http.form;
- import vibe.stream.wrapper;
- StringLengthCountingRange len;
- writeFormData(&len, form);
- req.contentType = "application/x-www-form-urlencoded";
- req.contentLength = len.count;
- auto rng = streamOutputRange(req.bodyWriter);
- writeFormData(&rng, form);
- }
- ///
- unittest {
- import vibe.core.log;
- import vibe.http.client;
- import vibe.http.form;
- import vibe.stream.operations;
- void sendForm()
- {
- requestHTTP("http://example.com/form",
- (scope req) {
- req.method = HTTPMethod.POST;
- req.writeFormBody(["field1": "value1", "field2": "value2"]);
- },
- (scope res) {
- logInfo("Response: %s", res.bodyReader.readAllUTF8());
- });
- }
- }
- /**
- Writes a `vibe.http.client.HTTPClientRequest` body as URL encoded form data.
- Params:
- req = Request object to write to.
- form = range of `t = Tuple!(string, string)`,
- where `t[0]` is the name and `t[1]` the
- value of a form entry.
- */
- void writeFormBody(PairRange)(HTTPClientRequest req, PairRange form)
- if(isTuple!(ElementType!PairRange) && ElementType!PairRange.length == 2)
- {
- import vibe.http.form;
- import vibe.stream.wrapper;
- StringLengthCountingRange len;
- writeFormData(&len, form.save);
- req.contentType = "application/x-www-form-urlencoded";
- req.contentLength = len.count;
- auto rng = streamOutputRange(req.bodyWriter);
- writeFormData(&rng, form);
- }
- ///
- unittest {
- import vibe.core.log;
- import vibe.http.client;
- import vibe.http.form;
- import vibe.stream.operations;
- import std.range;
- void sendForm()
- {
- string[] names = ["foo", "bar", "baz"];
- string[] values = ["1", "2", "3"];
- auto form = zip(names, values);
- requestHTTP("http://example.com/form",
- (scope req) {
- req.method = HTTPMethod.POST;
- req.writeFormBody(form);
- },
- (scope res) {
- logInfo("Response: %s", res.bodyReader.readAllUTF8());
- });
- }
- }
- /// private
- struct StringLengthCountingRange {
- import std.utf;
- size_t count = 0;
- void put(string str) { count += str.length; }
- void put(dchar ch) { count += codeLength!char(ch); }
- }
|