1 /******************************************************************************* 2 3 copyright: Copyright (c) 2004 Kris Bell. All rights reserved 4 5 license: BSD style: $(LICENSE) 6 7 version: Initial release: January 2006 8 9 author: Kris 10 11 *******************************************************************************/ 12 13 module tango.net.http.HttpPost; 14 15 public import tango.net.Uri; 16 17 private import tango.io.model.IConduit; 18 19 private import tango.net.http.HttpClient, 20 tango.net.http.HttpHeaders; 21 22 /******************************************************************************* 23 24 Supports the basic needs of a client sending POST requests to a 25 HTTP server. The following is a usage example: 26 27 --- 28 // open a web-page for posting (see HttpGet for simple reading) 29 auto post = new HttpPost ("http://yourhost/yourpath"); 30 31 // send, retrieve and display response 32 Cout (cast(char[]) post.write("posted data", "text/plain")); 33 --- 34 35 *******************************************************************************/ 36 37 class HttpPost : HttpClient 38 { 39 /*********************************************************************** 40 41 Create a client for the given URL. The argument should be 42 fully qualified with an "http:" or "https:" scheme, or an 43 explicit port should be provided. 44 45 ***********************************************************************/ 46 47 this (const(char)[] url) 48 { 49 this (new Uri(url)); 50 } 51 52 /*********************************************************************** 53 54 Create a client with the provided Uri instance. The Uri should 55 be fully qualified with an "http:" or "https:" scheme, or an 56 explicit port should be provided. 57 58 ***********************************************************************/ 59 60 this (Uri uri) 61 { 62 super (HttpClient.Post, uri); 63 64 // enable header duplication 65 getResponseHeaders().retain (true); 66 } 67 68 /*********************************************************************** 69 70 Send query params only 71 72 ***********************************************************************/ 73 74 void[] write () 75 { 76 return write (null); 77 } 78 79 /*********************************************************************** 80 81 Send raw data via the provided pump, and no query 82 params. You have full control over headers and so 83 on via this method. 84 85 ***********************************************************************/ 86 87 void[] write (Pump pump) 88 { 89 auto buffer = super.open (pump); 90 try { 91 // check return status for validity 92 auto status = super.getStatus(); 93 if (status is HttpResponseCode.OK || 94 status is HttpResponseCode.Created || 95 status is HttpResponseCode.Accepted) 96 buffer.load (getResponseHeaders().getInt (HttpHeader.ContentLength)); 97 } finally {close();} 98 99 return buffer.slice(); 100 } 101 102 /*********************************************************************** 103 104 Send content and no query params. The contentLength header 105 will be set to match the provided content, and contentType 106 set to the given type. 107 108 ***********************************************************************/ 109 110 void[] write (const(void)[] content, const(char)[] type) 111 { 112 auto headers = super.getRequestHeaders(); 113 114 headers.add (HttpHeader.ContentType, type); 115 headers.addInt (HttpHeader.ContentLength, content.length); 116 117 return write ((OutputBuffer b){b.append(content);}); 118 } 119 } 120 121 debug(HttpPost) 122 { 123 import tango.io.Console; 124 125 void main() 126 { 127 auto page = new HttpPost("http://driv.pl/tango/index.php"); 128 // Its important to set cookies below in order to parse post fields properly 129 page.getRequestHeaders().add(HttpHeader.AcceptCharset, "UTF-8,*"); 130 Cout("Enter your name: ").newline; 131 string name; 132 Cin.readln(name); 133 auto fields = "submit=send&nick=" ~ name; 134 Cout( cast(char[]) page.write(cast(void[]) fields, "application/x-www-form-urlencoded") )(); 135 } 136 }