OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
MultipartForm.cs
Go to the documentation of this file.
1 /*
2  * Copyright (c) Contributors, http://opensimulator.org/
3  * See CONTRIBUTORS.TXT for a full list of copyright holders.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the OpenSimulator Project nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 using System;
29 using System.Collections.Generic;
30 using System.Net;
31 using System.IO;
32 using System.Text;
33 
34 namespace OpenSim.Framework
35 {
36  public static class MultipartForm
37  {
38  #region Helper Classes
39 
40  public abstract class Element
41  {
42  public string Name;
43  }
44 
45  public class File : Element
46  {
47  public string Filename;
48  public string ContentType;
49  public byte[] Data;
50 
51  public File(string name, string filename, string contentType, byte[] data)
52  {
53  Name = name;
54  Filename = filename;
55  ContentType = contentType;
56  Data = data;
57  }
58  }
59 
60  public class Parameter : Element
61  {
62  public string Value;
63 
64  public Parameter(string name, string value)
65  {
66  Name = name;
67  Value = value;
68  }
69  }
70 
71  #endregion Helper Classes
72 
73  public static HttpWebResponse Post(HttpWebRequest request, List<Element> postParameters)
74  {
75  string boundary = Boundary();
76 
77  // Set up the request properties
78  request.Method = "POST";
79  request.ContentType = "multipart/form-data; boundary=" + boundary;
80 
81  #region Stream Writing
82 
83  using (MemoryStream formDataStream = new MemoryStream())
84  {
85  foreach (var param in postParameters)
86  {
87  if (param is File)
88  {
89  File file = (File)param;
90 
91  // Add just the first part of this param, since we will write the file data directly to the Stream
92  string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n",
93  boundary,
94  file.Name,
95  !String.IsNullOrEmpty(file.Filename) ? file.Filename : "tempfile",
96  file.ContentType);
97 
98  formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, header.Length);
99  formDataStream.Write(file.Data, 0, file.Data.Length);
100  }
101  else
102  {
103  Parameter parameter = (Parameter)param;
104 
105  string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}\r\n",
106  boundary,
107  parameter.Name,
108  parameter.Value);
109  formDataStream.Write(Encoding.UTF8.GetBytes(postData), 0, postData.Length);
110  }
111  }
112 
113  // Add the end of the request
114  byte[] footer = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
115  formDataStream.Write(footer, 0, footer.Length);
116 
117  request.ContentLength = formDataStream.Length;
118 
119  // Copy the temporary stream to the network stream
120  formDataStream.Seek(0, SeekOrigin.Begin);
121  using (Stream requestStream = request.GetRequestStream())
122  formDataStream.CopyStream(requestStream, (int)formDataStream.Length);
123  }
124 
125  #endregion Stream Writing
126 
127  return request.GetResponse() as HttpWebResponse;
128  }
129 
130  private static string Boundary()
131  {
132  Random rnd = new Random();
133  string formDataBoundary = String.Empty;
134 
135  while (formDataBoundary.Length < 15)
136  formDataBoundary = formDataBoundary + rnd.Next();
137 
138  formDataBoundary = formDataBoundary.Substring(0, 15);
139  formDataBoundary = "-----------------------------" + formDataBoundary;
140 
141  return formDataBoundary;
142  }
143  }
144 }
Parameter(string name, string value)
File(string name, string filename, string contentType, byte[] data)