2 // System.Web.HttpRequest
\r
5 // Patrik Torstensson (Patrik.Torstensson@labs2.com)
\r
8 using System.Collections;
\r
9 using System.Collections.Specialized;
\r
12 using System.Web.Configuration;
\r
14 namespace System.Web {
\r
15 [MonoTODO("Review security in all path access function")]
\r
16 public sealed class HttpRequest {
\r
17 private string [] _arrAcceptTypes;
\r
18 private string [] _arrUserLanguages;
\r
20 private byte [] _arrRawContent;
\r
21 private int _iContentLength;
\r
23 private string _sContentType;
\r
24 private string _sHttpMethod;
\r
25 private string _sRawUrl;
\r
26 private string _sUserAgent;
\r
27 private string _sUserHostAddress;
\r
28 private string _sUserHostName;
\r
29 private string _sPath;
\r
30 private string _sPathInfo;
\r
31 private string _sFilePath;
\r
32 private string _sPathTranslated;
\r
33 private string _sQueryStringRaw;
\r
34 private string _sRequestType;
\r
35 private string _sRequestRootVirtualDir;
\r
37 private Encoding _oContentEncoding;
\r
39 private Uri _oUriReferrer;
\r
42 private int _iTotalBytes;
\r
44 private HttpContext _oContext;
\r
46 private HttpWorkerRequest _WorkerRequest;
\r
47 private HttpRequestStream _oInputStream;
\r
48 private HttpClientCertificate _ClientCert;
\r
50 private HttpValueCollection _oServerVariables;
\r
51 private HttpValueCollection _oHeaders;
\r
52 private HttpValueCollection _oQueryString;
\r
53 private HttpValueCollection _oFormData;
\r
54 private HttpValueCollection _oParams;
\r
56 private HttpBrowserCapabilities _browser;
\r
58 public HttpRequest(string Filename, string Url, string Querystring) {
\r
59 _iContentLength = -1;
\r
62 _WorkerRequest = null;
\r
63 _sPathTranslated = Filename;
\r
64 _sRequestType = "GET";
\r
65 _sHttpMethod = "GET";
\r
66 _oUrl = new Uri(Url);
\r
67 _sPath = _oUrl.AbsolutePath;
\r
69 _sQueryStringRaw = Querystring;
\r
70 _oQueryString = new HttpValueCollection(Querystring, true, Encoding.Default);
\r
73 internal HttpRequest(HttpWorkerRequest WorkRequest, HttpContext Context) {
\r
74 _WorkerRequest = WorkRequest;
\r
75 _oContext = Context;
\r
77 _iContentLength = -1;
\r
81 static private string MakeServerVariableFromHeader(string header) {
\r
82 return "HTTP_" + header.ToUpper().Replace("-", "_");
\r
85 [MonoTODO("Need to support non-raw mode also..")]
\r
86 private string GetAllHeaders(bool Raw) {
\r
87 StringBuilder oData;
\r
89 if (null == _WorkerRequest) {
\r
93 oData = new StringBuilder(512);
\r
95 string sHeaderValue;
\r
99 // Add all know headers
\r
100 for (; iCount != 40; iCount++) {
\r
101 sHeaderValue = _WorkerRequest.GetKnownRequestHeader(iCount);
\r
102 if (null != sHeaderValue && sHeaderValue.Length > 0) {
\r
103 sHeaderName = _WorkerRequest.GetKnownRequestHeader(iCount);
\r
104 if (null != sHeaderName && sHeaderName.Length > 0) {
\r
105 oData.Append(sHeaderName);
\r
106 oData.Append(": ");
\r
107 oData.Append(sHeaderValue);
\r
108 oData.Append("\r\n");
\r
113 // Get all other headers
\r
114 string [][] arrUnknownHeaders = _WorkerRequest.GetUnknownRequestHeaders();
\r
115 if (null != arrUnknownHeaders) {
\r
116 for (iCount = 0; iCount != arrUnknownHeaders.Length; iCount++) {
\r
117 oData.Append(arrUnknownHeaders[iCount][0]);
\r
118 oData.Append(": ");
\r
119 oData.Append(arrUnknownHeaders[iCount][1]);
\r
120 oData.Append("\r\n");
\r
124 return oData.ToString();
\r
127 [MonoTODO("We need to handly 'dynamic' variables like AUTH_USER, that can be changed during runtime... special collection")]
\r
128 private void ParseServerVariables() {
\r
129 if (null == _WorkerRequest) {
\r
133 if (_oServerVariables == null) {
\r
136 _oServerVariables = new HttpValueCollection();
\r
138 _oServerVariables.Add("ALL_HTTP", GetAllHeaders(false));
\r
139 _oServerVariables.Add("ALL_RAW", GetAllHeaders(true));
\r
141 _oServerVariables.Add("APPL_MD_PATH", _WorkerRequest.GetServerVariable("APPL_MD_PATH"));
\r
142 _oServerVariables.Add("AUTH_PASSWORD", _WorkerRequest.GetServerVariable("AUTH_PASSWORD"));
\r
143 _oServerVariables.Add("CERT_COOKIE", _WorkerRequest.GetServerVariable("CERT_COOKIE"));
\r
144 _oServerVariables.Add("CERT_FLAGS", _WorkerRequest.GetServerVariable("CERT_FLAGS"));
\r
145 _oServerVariables.Add("CERT_ISSUER", _WorkerRequest.GetServerVariable("CERT_ISSUER"));
\r
146 _oServerVariables.Add("CERT_KEYSIZE", _WorkerRequest.GetServerVariable("CERT_KEYSIZE"));
\r
147 _oServerVariables.Add("CERT_SECRETKEYSIZE", _WorkerRequest.GetServerVariable("CERT_SECRETKEYSIZE"));
\r
148 _oServerVariables.Add("CERT_SERIALNUMBER", _WorkerRequest.GetServerVariable("CERT_SERIALNUMBER"));
\r
149 _oServerVariables.Add("CERT_SERVER_ISSUER", _WorkerRequest.GetServerVariable("CERT_SERVER_ISSUER"));
\r
150 _oServerVariables.Add("CERT_SERVER_SUBJECT", _WorkerRequest.GetServerVariable("CERT_SERVER_SUBJECT"));
\r
151 _oServerVariables.Add("CERT_SUBJECT", _WorkerRequest.GetServerVariable("CERT_SUBJECT"));
\r
153 _oServerVariables.Add("GATEWAY_INTERFACE", _WorkerRequest.GetServerVariable("GATEWAY_INTERFACE"));
\r
154 _oServerVariables.Add("HTTPS", _WorkerRequest.GetServerVariable("HTTPS"));
\r
155 _oServerVariables.Add("HTTPS_KEYSIZE", _WorkerRequest.GetServerVariable("HTTPS_KEYSIZE"));
\r
156 _oServerVariables.Add("HTTPS_SECRETKEYSIZE", _WorkerRequest.GetServerVariable("HTTPS_SECRETKEYSIZE"));
\r
158 _oServerVariables.Add("CONTENT_TYPE", ContentType);
\r
159 _oServerVariables.Add("HTTPS_SERVER_ISSUER", _WorkerRequest.GetServerVariable("HTTPS_SERVER_ISSUER"));
\r
160 _oServerVariables.Add("HTTPS_SERVER_SUBJECT", _WorkerRequest.GetServerVariable("HTTPS_SERVER_SUBJECT"));
\r
161 _oServerVariables.Add("INSTANCE_ID", _WorkerRequest.GetServerVariable("INSTANCE_ID"));
\r
162 _oServerVariables.Add("INSTANCE_META_PATH", _WorkerRequest.GetServerVariable("INSTANCE_META_PATH"));
\r
163 _oServerVariables.Add("LOCAL_ADDR", _WorkerRequest.GetLocalAddress());
\r
164 _oServerVariables.Add("REMOTE_ADDR", UserHostAddress);
\r
165 _oServerVariables.Add("REMOTE_HOST", UserHostName);
\r
166 _oServerVariables.Add("REQUEST_METHOD", HttpMethod);
\r
167 _oServerVariables.Add("SERVER_NAME", _WorkerRequest.GetServerName());
\r
168 _oServerVariables.Add("SERVER_PORT", _WorkerRequest.GetLocalPort().ToString());
\r
169 _oServerVariables.Add("SERVER_PROTOCOL", _WorkerRequest.GetHttpVersion());
\r
170 _oServerVariables.Add("SERVER_SOFTWARE", _WorkerRequest.GetServerVariable("SERVER_SOFTWARE"));
\r
172 if (_WorkerRequest.IsSecure()) {
\r
173 _oServerVariables.Add("SERVER_PORT_SECURE", "1");
\r
175 _oServerVariables.Add("SERVER_PORT_SECURE", "0");
\r
178 sTmp = _WorkerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentLength);
\r
179 if (null != sTmp) {
\r
180 _oServerVariables.Add("CONTENT_LENGTH", sTmp);
\r
183 // TODO: Should be dynamic
\r
184 if (null != _oContext.User && _oContext.User.Identity.IsAuthenticated) {
\r
185 _oServerVariables.Add("AUTH_TYPE", _oContext.User.Identity.AuthenticationType);
\r
186 _oServerVariables.Add("AUTH_USER", _oContext.User.Identity.Name);
\r
188 _oServerVariables.Add("AUTH_TYPE", "");
\r
189 _oServerVariables.Add("AUTH_USER", "");
\r
192 _oServerVariables.Add("PATH_INFO", PathInfo);
\r
193 _oServerVariables.Add("PATH_TRANSLATED", PhysicalPath);
\r
194 _oServerVariables.Add("QUERY_STRING", QueryStringRaw);
\r
195 _oServerVariables.Add("SCRIPT_NAME", FilePath);
\r
198 _oServerVariables.MakeReadOnly();
\r
202 [MonoTODO("Handle Multipart data also, content-encoding check")]
\r
203 private void ParseFormData() {
\r
204 if (_oFormData == null) {
\r
205 byte [] arrData = GetRawContent();
\r
206 _oFormData = new HttpValueCollection(ContentEncoding.GetString(arrData), true, ContentEncoding);
\r
214 [MonoTODO("Handle Multipart data, max content length?")]
\r
215 private byte [] GetRawContent() {
\r
216 if (null == _arrRawContent) {
\r
217 if (null == _WorkerRequest) {
\r
221 // TODO: Check max length?
\r
222 _arrRawContent = _WorkerRequest.GetPreloadedEntityBody();
\r
223 if (!_WorkerRequest.IsEntireEntityBodyIsPreloaded()) {
\r
227 arrBuffer = new byte[16384];
\r
228 int iLoaded = 16384;
\r
230 while (iLoaded == arrBuffer.Length) {
\r
231 iLoaded = _WorkerRequest.ReadEntityBody(arrBuffer, arrBuffer.Length);
\r
234 arrTemp = new byte[_arrRawContent.Length + iLoaded];
\r
236 Array.Copy(_arrRawContent, 0, arrTemp, 0, _arrRawContent.Length);
\r
237 Array.Copy(arrBuffer, 0, arrTemp, _arrRawContent.Length, iLoaded);
\r
239 _arrRawContent = arrTemp;
\r
244 return _arrRawContent;
\r
247 public string [] AcceptTypes {
\r
249 if (null == _arrAcceptTypes && null != _WorkerRequest) {
\r
250 _arrAcceptTypes = HttpHelper.ParseMultiValueHeader(_WorkerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderAccept));
\r
253 return _arrAcceptTypes;
\r
258 public string ApplicationPath {
\r
260 if (null != _WorkerRequest) {
\r
261 return _WorkerRequest.GetAppPath();
\r
268 public HttpBrowserCapabilities Browser
\r
270 get { return _browser; }
\r
272 set { _browser = value; }
\r
275 public HttpClientCertificate ClientCertificate {
\r
277 if (null == _ClientCert) {
\r
278 _ClientCert = new HttpClientCertificate(_oContext);
\r
281 return _ClientCert;
\r
285 [MonoTODO("Get content encoding from Syste.Web.Configuration namespace")]
\r
286 public Encoding ContentEncoding {
\r
288 if (_oContentEncoding == null) {
\r
289 // TODO: Get from config what is the default encoding
\r
290 // TODO: Should we get encoding from HttpHeaders? Just get charset from ContentType and the get encoding..
\r
291 _oContentEncoding = Encoding.Default;
\r
294 return _oContentEncoding;
\r
298 _oContentEncoding = value;
\r
302 public int ContentLength {
\r
304 if (_iContentLength == -1 && null != _WorkerRequest) {
\r
305 string sLength = _WorkerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentLength);
\r
306 if (sLength != null) {
\r
308 _iContentLength = Int32.Parse(sLength);
\r
315 if (_iContentLength < 0) {
\r
316 _iContentLength = 0;
\r
319 return _iContentLength;
\r
323 public string ContentType {
\r
325 if (null == _sContentType) {
\r
326 if (null != _WorkerRequest) {
\r
327 _sContentType = _WorkerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentType);
\r
330 if (null == _sContentType) {
\r
331 _sContentType = string.Empty;
\r
335 return _sContentType;
\r
340 public HttpCookieCollection Cookies {
\r
342 throw new NotImplementedException();
\r
347 public string CurrentExecutionFilePath {
\r
349 throw new NotImplementedException();
\r
353 public string FilePath {
\r
355 if (null == _sFilePath && null != _WorkerRequest) {
\r
356 _sFilePath = _WorkerRequest.GetFilePath();
\r
364 public HttpFileCollection Files {
\r
366 throw new NotImplementedException();
\r
370 [MonoTODO("Use stream filter in the request stream")]
\r
371 public Stream Filter {
\r
373 throw new NotImplementedException();
\r
377 throw new NotImplementedException();
\r
382 public NameValueCollection Form {
\r
386 return (NameValueCollection) _oFormData;
\r
390 public NameValueCollection Headers {
\r
392 if (_oHeaders == null) {
\r
393 _oHeaders = new HttpValueCollection();
\r
395 if (null != _WorkerRequest) {
\r
396 string sHeaderValue;
\r
397 string sHeaderName;
\r
400 // Add all know headers
\r
401 for (; iCount != 40; iCount++) {
\r
402 sHeaderValue = _WorkerRequest.GetKnownRequestHeader(iCount);
\r
403 if (null != sHeaderValue && sHeaderValue.Length > 0) {
\r
404 sHeaderName = _WorkerRequest.GetKnownRequestHeader(iCount);
\r
405 if (null != sHeaderName && sHeaderName.Length > 0) {
\r
406 _oHeaders.Add(sHeaderName, sHeaderValue);
\r
411 // Get all other headers
\r
412 string [][] arrUnknownHeaders = _WorkerRequest.GetUnknownRequestHeaders();
\r
413 if (null != arrUnknownHeaders) {
\r
414 for (iCount = 0; iCount != arrUnknownHeaders.Length; iCount++) {
\r
415 _oHeaders.Add(arrUnknownHeaders[iCount][0], arrUnknownHeaders[iCount][1]);
\r
420 // Make headers read-only
\r
421 _oHeaders.MakeReadOnly();
\r
424 return (NameValueCollection) _oHeaders;
\r
428 public string HttpMethod {
\r
430 if (null == _sHttpMethod) {
\r
431 if (null != _WorkerRequest) {
\r
432 _sHttpMethod = _WorkerRequest.GetHttpVerbName().ToUpper();
\r
435 if (_sHttpMethod == null) {
\r
436 _sHttpMethod = "GET";
\r
440 return _sHttpMethod;
\r
444 public Stream InputStream {
\r
446 if (_oInputStream == null) {
\r
447 byte [] arrInputData = GetRawContent();
\r
449 if (null != arrInputData) {
\r
450 _oInputStream = new HttpRequestStream(arrInputData, 0, arrInputData.Length);
\r
452 _oInputStream = new HttpRequestStream(null, 0, 0);
\r
456 return _oInputStream;
\r
460 public bool IsAuthenticated {
\r
462 if (_oContext != null && _oContext.User != null && _oContext.User.Identity != null) {
\r
463 return _oContext.User.Identity.IsAuthenticated;
\r
470 public bool IsSecureConnection {
\r
472 if (null != _WorkerRequest) {
\r
473 return _WorkerRequest.IsSecure();
\r
480 [MonoTODO("Call item in querystring, form, cookie and servervariables")]
\r
481 public string this [string sKey] {
\r
483 throw new NotImplementedException();
\r
487 [MonoTODO("Add cookie collection to our Params collection via merge")]
\r
488 public NameValueCollection Params {
\r
490 if (_oParams == null) {
\r
491 _oParams = new HttpValueCollection();
\r
493 _oParams.Merge(QueryString);
\r
494 _oParams.Merge(Form);
\r
495 _oParams.Merge(ServerVariables);
\r
498 _oParams.MakeReadOnly();
\r
501 return (NameValueCollection) _oParams;
\r
505 public string Path {
\r
507 if (_sPath == null) {
\r
508 if (null != _WorkerRequest) {
\r
509 _sPath = _WorkerRequest.GetUriPath();
\r
512 if (_sPath == null) {
\r
513 _sPath = string.Empty;
\r
521 public string PathInfo {
\r
523 if (_sPathInfo == null) {
\r
524 if (null != _WorkerRequest) {
\r
525 _sPathInfo = _WorkerRequest.GetPathInfo();
\r
528 if (_sPathInfo == null) {
\r
529 _sPathInfo = string.Empty;
\r
537 public string PhysicalApplicationPath {
\r
539 if (null != _WorkerRequest) {
\r
540 return _WorkerRequest.GetAppPathTranslated();
\r
547 public string PhysicalPath {
\r
549 if (null != _WorkerRequest) {
\r
550 _sPathTranslated = _WorkerRequest.GetFilePathTranslated();
\r
551 if (null == _sPathTranslated) {
\r
552 _sPathTranslated = _WorkerRequest.MapPath(FilePath);
\r
556 return _sPathTranslated;
\r
560 public NameValueCollection QueryString {
\r
562 if (_oQueryString == null) {
\r
563 _oQueryString = new HttpValueCollection(QueryStringRaw, true, Encoding.UTF8);
\r
566 return _oQueryString;
\r
570 // Used to parse the querystring
\r
571 internal string QueryStringRaw {
\r
573 if (_sQueryStringRaw == null && null != _WorkerRequest) {
\r
574 byte [] arrQuerystringBytes = _WorkerRequest.GetQueryStringRawBytes();
\r
575 if (null != arrQuerystringBytes && arrQuerystringBytes.Length > 0) {
\r
576 _sQueryStringRaw = ContentEncoding.GetString(arrQuerystringBytes);
\r
578 _sQueryStringRaw = _WorkerRequest.GetQueryString();
\r
582 if (_sQueryStringRaw == null) {
\r
583 _sQueryStringRaw = string.Empty;
\r
586 return _sQueryStringRaw;
\r
590 public string RawUrl {
\r
592 if (null == _sRawUrl) {
\r
593 if (null != _WorkerRequest) {
\r
594 _sRawUrl = _WorkerRequest.GetRawUrl();
\r
597 if (QueryStringRaw != null && QueryStringRaw.Length > 0) {
\r
598 _sRawUrl = _sRawUrl + "?" + QueryStringRaw;
\r
607 public string RequestType {
\r
609 if (null == _sRequestType) {
\r
613 return _sRequestType;
\r
617 _sRequestType = value;
\r
622 public NameValueCollection ServerVariables {
\r
624 ParseServerVariables();
\r
626 return (NameValueCollection) _oServerVariables;
\r
630 public int TotalBytes {
\r
632 if (_iTotalBytes == -1) {
\r
633 if (null != InputStream) {
\r
634 _iTotalBytes = (int) InputStream.Length;
\r
640 return _iTotalBytes;
\r
646 if (null == _oUrl) {
\r
647 _oUrl = new Uri(RawUrl);
\r
654 public Uri UrlReferrer {
\r
656 if (null == _oUriReferrer && null != _WorkerRequest) {
\r
657 string sReferrer = _WorkerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderReferer);
\r
658 if (null != sReferrer && sReferrer.Length > 0) {
\r
660 if (sReferrer.IndexOf("://") >= 0) {
\r
661 _oUriReferrer = new Uri(sReferrer);
\r
663 _oUriReferrer = new Uri(this.Url, sReferrer);
\r
666 catch (Exception) {
\r
671 return _oUriReferrer;
\r
675 public string UserAgent {
\r
677 if (_sUserAgent == null && _WorkerRequest != null) {
\r
678 _sUserAgent = _WorkerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderUserAgent);
\r
681 if (_sUserAgent == null) {
\r
682 _sUserAgent = string.Empty;
\r
685 return _sUserAgent;
\r
689 public string UserHostAddress {
\r
691 if (_sUserHostAddress == null && null != _WorkerRequest) {
\r
692 _sUserHostAddress = _WorkerRequest.GetRemoteAddress();
\r
695 if (_sUserHostAddress == null || _sUserHostAddress.Length == 0) {
\r
696 _sUserHostAddress = "127.0.0.1";
\r
699 return _sUserHostAddress;
\r
703 public string UserHostName {
\r
705 if (_sUserHostName == null && null != _WorkerRequest) {
\r
706 _sUserHostName = _WorkerRequest.GetRemoteName();
\r
709 if (_sUserHostName == null || _sUserHostName.Length == 0) {
\r
710 _sUserHostName = UserHostAddress;
\r
713 return _sUserHostName;
\r
717 public string [] UserLanguages {
\r
719 if (_arrUserLanguages == null && null != _WorkerRequest) {
\r
720 _arrUserLanguages = HttpHelper.ParseMultiValueHeader(_WorkerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderAcceptLanguage));
\r
723 return _arrUserLanguages;
\r
727 public byte [] BinaryRead(int count) {
\r
728 int iSize = TotalBytes;
\r
730 throw new ArgumentException();
\r
733 byte [] arrData = new byte[iSize];
\r
735 int iRetSize = InputStream.Read(arrData, 0, iSize);
\r
736 if (iRetSize != iSize) {
\r
737 byte [] tmpData = new byte[iRetSize];
\r
738 if (iRetSize > 0) {
\r
739 Array.Copy(arrData, 0, tmpData, 0, iRetSize);
\r
748 public int [] MapImageCoordinates(string ImageFieldName) {
\r
749 NameValueCollection oItems;
\r
751 if (HttpMethod == "GET" || HttpMethod == "HEAD") {
\r
752 oItems = QueryString;
\r
753 } else if (HttpMethod == "POST") {
\r
759 int [] arrRet = null;
\r
761 string sX = oItems.Get(ImageFieldName + ".x");
\r
762 string sY = oItems.Get(ImageFieldName + ".y");
\r
764 if (null != sX && null != sY) {
\r
765 int [] arrTmp = new Int32[2];
\r
766 arrRet[0] = Int32.Parse(sX);
\r
767 arrRet[1] = Int32.Parse(sY);
\r
772 catch (Exception) {
\r
778 public string MapPath(string VirtualPath) {
\r
779 if (null == _sRequestRootVirtualDir) {
\r
780 if (null == FilePath || FilePath.Length == 0) {
\r
781 throw new ArgumentException("Filepath can't be empty");
\r
784 if (FilePath[0] != '/') {
\r
785 throw new ArgumentException("Filepath must be a root");
\r
788 _sRequestRootVirtualDir = FilePath.Substring(0, FilePath.LastIndexOf('/'));
\r
789 if (_sRequestRootVirtualDir.Length == 0) {
\r
790 _sRequestRootVirtualDir = "/";
\r
794 return MapPath(VirtualPath, _sRequestRootVirtualDir, true);
\r
797 [MonoTODO("Build a path to send to MapPath in the workerrequest")]
\r
798 public string MapPath(string virtualPath, string baseVirtualDir, bool allowCrossAppMapping) {
\r
799 throw new NotImplementedException();
\r
802 public void SaveAs(string filename, bool includeHeaders) {
\r
804 TextWriter oWriter;
\r
805 HttpRequestStream oData;
\r
807 oFile = new FileStream(filename, FileMode.CreateNew);
\r
808 if (includeHeaders) {
\r
809 oWriter = new StreamWriter(oFile);
\r
810 oWriter.Write(HttpMethod + " " + Path);
\r
812 if (QueryStringRaw != null && QueryStringRaw.Length > 0)
\r
813 oWriter.Write("?" + QueryStringRaw);
\r
814 if (_WorkerRequest != null) {
\r
815 oWriter.Write(" " + _WorkerRequest.GetHttpVersion() + "\r\n");
\r
816 oWriter.Write(GetAllHeaders(true));
\r
818 oWriter.Write("\r\n");
\r
821 oWriter.Write("\r\n");
\r
825 oData = (HttpRequestStream) InputStream;
\r
827 if (oData.DataLength > 0) {
\r
828 oFile.Write(oData.Data, oData.DataOffset, oData.DataLength);
\r