jschementi / ironruby forked from ironruby/ironruby

Microsoft's Ruby language compiler that is built on top of the Dynamic Language Runtime.

This URL has Read+Write access

Jimmy Schementi (author)
Fri May 29 13:49:16 -0700 2009
commit  a271880bc1aef4a7845291535524df76882ec9b4
tree    2b16b0cb332fd89681a5a783d6989abe4ea1d6a5
parent  84f13b1901330326bc7a098463575a7d1cdc2d37
ironruby / Merlin / Main / Hosts / IronRuby.Rack / Request.cs
100644 100 lines (84 sloc) 3.94 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using IronRuby.Builtins;
 
namespace IronRuby.Rack {
    public class Request {
 
        private readonly Hash headers;
        private readonly string queryString;
        private readonly string body;
        private readonly string scheme;
 
        internal readonly HttpRequestBase OrigionalRequest;
        
        public Request(HttpRequestBase request) {
            if (request == null) {
                throw new ArgumentNullException("request");
            }
 
            // http or https
            this.scheme = request.Url.Scheme;
 
            // go through the headers of the request and move to a more tenable
            // storage location than NameValueCollection
            Dictionary<object, object> headers = new Dictionary<object, object>();
            foreach (string key in request.Headers.AllKeys) {
                string value = request.Headers.Get(key);
                if (string.IsNullOrEmpty(value)) {
                    continue;
                }
                headers.Add(key, value);
            }
 
            // explicitly put in Content-Type and Content-Length
            headers["Content-Type"] = request.ContentType;
            headers["Content-Length"] = request.ContentLength;
            this.headers = new Hash(headers);
 
            // recombine the query string into 1 single string
            StringBuilder qs = new StringBuilder();
            foreach (string key in request.QueryString.AllKeys) {
                string value = request.QueryString.Get(key);
                if (string.IsNullOrEmpty(value)) {
                    continue;
                }
                qs.Append(key).Append('=').Append(value).Append('&');
            }
 
            this.queryString = qs.ToString();
 
            // was form data posted?
            if (request.ContentType.StartsWith("application/x-www-form-urlencoded") ||
                request.ContentType.StartsWith("multipart/form-data")) {
                // yep, so we need to build a body string that contains the form data so that
                // Rack can do the correct thing. If it is multipart/form-data, we change it
                // to x-www-form-urlencoded as that is easier to generate
                if (request.ContentType.StartsWith("multipart/form-data")) {
                    headers["Content-Type"] = "application/x-www-form-urlencoded";
                }
                StringBuilder body = new StringBuilder();
                foreach (string key in request.Form.AllKeys) {
                    string value = request.Form.Get(key);
                    if (string.IsNullOrEmpty(value)) {
                        continue;
                    }
                    qs.Append(key).Append('=').Append(value).Append('&');
                }
                this.body = qs.ToString();
            } else {
                // not form data, not sure what to do about files right now, going to
                // punt and not deal with it right now. Not sure what do do about other
                // types of body content either. If text/*, could read it in using the
                // encoding. Again going to punt for now and not deal with it.
            }
 
            // Save the origional request incase it's needed.
            OrigionalRequest = request;
        }
 
        /// <summary>
        /// Gets the headers of this HTTP request
        /// </summary>
        public Hash Headers { get { return this.headers; } }
 
        /// <summary>
        /// Gets the query string of this HTTP request
        /// </summary>
        public string QueryString { get { return this.queryString; } }
 
        /// <summary>
        /// Gets the body of this HTTP request
        /// </summary>
        public string Body { get { return this.body; } }
 
        public string Scheme { get { return this.scheme; } }
    }
}