Advertisement
Guest User

Untitled

a guest
May 6th, 2015
217
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 13.81 KB | None | 0 0
  1.  
  2.     /// <summary>
  3.     /// Reactor HTTP Server Response.
  4.     /// </summary>
  5.     public class ServerResponse : Reactor.IWritable {
  6.  
  7.         private Reactor.IWritable     writable;
  8.         private Reactor.Async.Queue   queue;
  9.         private Reactor.Http.Headers  headers;
  10.         private Reactor.Http.Cookies  cookies;
  11.         private System.Version        version;
  12.         private System.Int32          status_code;
  13.         private System.String         status_description;
  14.  
  15.         private bool                  header_sent;
  16.  
  17.         #region Constructors
  18.  
  19.         public ServerResponse(Reactor.IWritable writable) {
  20.             this.writable           = writable;
  21.             this.queue              = Reactor.Async.Queue.Create(1);
  22.             this.headers            = new Reactor.Http.Headers();
  23.             this.cookies            = new Reactor.Http.Cookies();
  24.             this.version            = new Version(1, 1);
  25.             this.status_code        = 200;
  26.             this.status_description = "OK";
  27.             this.header_sent        = false;
  28.  
  29.             /* defaults */
  30.             this.headers["Server"]            = "Reactor-HTTP Server";
  31.             this.headers["Transfer-Encoding"] = "chunked";
  32.             this.headers["Connection"]        = "closed";
  33.             this.headers["Cache-Control"]     = "no-cache";
  34.             this.headers["Date"]              = DateTime.UtcNow.ToString("r");
  35.         }
  36.  
  37.         #endregion
  38.  
  39.         #region Properties
  40.  
  41.         public Reactor.Http.Headers Headers            {
  42.             get {
  43.                 return this.headers;
  44.             }
  45.         }
  46.  
  47.         public Reactor.Http.Cookies Cookies            {
  48.             get {
  49.                 return this.cookies;
  50.             }
  51.         }
  52.  
  53.         public int                  StatusCode        
  54.         {
  55.             get {
  56.                 return this.status_code;
  57.             }
  58.             set {
  59.                 this.status_code = value;
  60.             }
  61.         }
  62.  
  63.         public string               StatusDescription  {
  64.             get {
  65.                 return this.status_description;
  66.             }
  67.             set {
  68.                 this.status_description = value;
  69.             }
  70.         }
  71.  
  72.         public long                 ContentLength      {
  73.             get  {
  74.                 long result = 0;
  75.                 long.TryParse(this.headers["Content-Length"], out result);
  76.                 return result;
  77.             }
  78.             set  {
  79.                 this.headers["Content-Length"] = value.ToString();
  80.             }
  81.         }
  82.  
  83.         public string               ContentType        {
  84.             get {
  85.                 return this.headers["Content-Type"];
  86.             }
  87.             set {
  88.                 this.headers["Content-Type"] = value;
  89.             }
  90.         }
  91.  
  92.         #endregion
  93.  
  94.         #region Events
  95.  
  96.         public void OnDrain(Action callback) {
  97.             this.writable.OnDrain(callback);
  98.         }
  99.  
  100.         public void OnceDrain(Action callback) {
  101.             this.writable.OnceDrain(callback);
  102.         }
  103.  
  104.         public void RemoveDrain(Action callback) {
  105.             this.writable.RemoveDrain(callback);
  106.         }
  107.  
  108.         public void OnEnd(Action callback) {
  109.             this.writable.OnEnd(callback);
  110.         }
  111.  
  112.         public void RemoveEnd(Action callback) {
  113.             this.writable.RemoveEnd(callback);
  114.         }
  115.  
  116.         #endregion
  117.  
  118.         #region Methods
  119.  
  120.         /// <summary>
  121.         /// Writes this buffer to the stream. This method returns a Reactor.Future
  122.         /// which resolves once this buffer has been written.
  123.         /// </summary>
  124.         /// <param name="buffer"></param>
  125.         /// <returns></returns>
  126.         public Reactor.Async.Future Write (Reactor.Buffer buffer) {
  127.             return this._Write(buffer);
  128.         }
  129.  
  130.         /// <summary>
  131.         /// Flushes this stream. This method returns a Reactor.Future which
  132.         /// resolves once the stream has been flushed.
  133.         /// </summary>
  134.         /// <returns></returns>
  135.         public Reactor.Async.Future Flush() {
  136.             return this._Flush();
  137.         }
  138.  
  139.         /// <summary>
  140.         /// Ends and disposes of the underlying resource. This method returns
  141.         /// a Reactor.Future which resolves once this stream has been ended.
  142.         /// </summary>
  143.         /// <returns></returns>
  144.         public Reactor.Async.Future End () {
  145.             return this._End();
  146.         }
  147.  
  148.         /// <summary>
  149.         /// Forces buffering of all writes. Buffered data will be
  150.         /// flushed either at .Uncork() or at .End() call.
  151.         /// </summary>
  152.         public void Cork() {
  153.             this.writable.Cork();
  154.         }
  155.  
  156.         /// <summary>
  157.         /// Flush all data, buffered since .Cork() call.
  158.         /// </summary>
  159.         public void Uncork() {
  160.              this.writable.Uncork();
  161.         }
  162.  
  163.         public void OnError     (Reactor.Action<Exception> callback)
  164.         {
  165.             this.writable.OnError(callback);
  166.         }
  167.  
  168.         public void RemoveError (Reactor.Action<Exception> callback) {
  169.  
  170.             this.writable.RemoveError(callback);
  171.         }
  172.  
  173.         #endregion
  174.  
  175.         #region Internal
  176.  
  177.         /// <summary>
  178.         /// Writes headers to this writable. If headers
  179.         /// have already been sent, this call is resolved
  180.         /// immediately. In addition, once the headers
  181.         /// have been sent, this method will detect
  182.         /// the transfer-encoding as 'chunked' and
  183.         /// swap out this writable for a chunked body
  184.         /// writable.
  185.         /// </summary>
  186.         /// <returns></returns>
  187.         private Reactor.Async.Future _WriteHeaders() {
  188.             if(this.header_sent) return Reactor.Async.Future.Resolved();
  189.             return new Reactor.Async.Future((resolve, reject) => {
  190.                 var buffer = Reactor.Buffer.Create(128);
  191.                 buffer.Write("HTTP/{0} {1} {2}\r\n", version, status_code, status_description);
  192.                 buffer.Write(this.headers.ToString());
  193.                 this.writable.Write(buffer)
  194.                              .Then(() => {
  195.                                 this.header_sent = true;
  196.                                 this.writable    = (this.headers["Transfer-Encoding"] == "chunked") ?
  197.                                     (Reactor.IWritable)new Reactor.Http2.Protocol.ChunkedBodyWriter(this.writable) :
  198.                                     (Reactor.IWritable)this.writable;
  199.                              }).Then(resolve)
  200.                                .Error(reject);
  201.             });
  202.         }
  203.  
  204.         /// <summary>
  205.         /// Writes this buffer to the underlying writable.
  206.         /// </summary>
  207.         /// <param name="buffer"></param>
  208.         /// <returns></returns>
  209.         private Reactor.Async.Future _Write (Reactor.Buffer buffer) {
  210.             return new Reactor.Async.Future((resolve, reject) => {
  211.                 this.queue.Run(next => {
  212.                     this._WriteHeaders().Then(() => {
  213.                         this.writable.Write(buffer)
  214.                                      .Then(resolve)
  215.                                      .Error(reject)
  216.                                      .Finally(next);
  217.                     }).Error(reject)
  218.                       .Finally(next);
  219.                 });
  220.             });
  221.         }
  222.  
  223.         /// <summary>
  224.         /// Flushes the underlying writable.
  225.         /// </summary>
  226.         /// <returns></returns>
  227.         private Reactor.Async.Future _Flush () {
  228.             return new Reactor.Async.Future((resolve, reject) => {
  229.                 this.queue.Run(next => {
  230.                     this._WriteHeaders().Then(() => {
  231.                         this.writable.Flush()
  232.                                      .Then(resolve)
  233.                                      .Error(reject)
  234.                                      .Finally(next);
  235.                     }).Error(reject)
  236.                       .Finally(next);
  237.                 });
  238.             });
  239.         }
  240.  
  241.         /// <summary>
  242.         /// Ends the underlying writable.
  243.         /// </summary>
  244.         /// <returns></returns>
  245.         private Reactor.Async.Future _End () {
  246.             return new Reactor.Async.Future((resolve, reject) => {
  247.                 this.queue.Run(next => {
  248.                     this._WriteHeaders().Then(() => {
  249.                         this.writable.End()
  250.                                      .Then(resolve)
  251.                                      .Error(reject)
  252.                                      .Finally(next);
  253.                     }).Error(reject)
  254.                       .Finally(next);
  255.                 });
  256.             });
  257.         }
  258.  
  259.         #endregion
  260.  
  261.         #region Buffer
  262.  
  263.         /// <summary>
  264.         /// Writes this data to the stream.
  265.         /// </summary>
  266.         /// <param name="buffer"></param>
  267.         /// <param name="index"></param>
  268.         /// <param name="count"></param>
  269.         /// <returns>A future resolved when this write has completed.</returns>
  270.         public Reactor.Async.Future Write (byte[] buffer, int index, int count) {
  271.             return this.Write(Reactor.Buffer.Create(buffer, 0, count));
  272.         }
  273.  
  274.         /// <summary>
  275.         /// Writes this data to the stream.
  276.         /// </summary>
  277.         /// <param name="buffer"></param>
  278.         /// <returns>A future resolved when this write has completed.</returns>
  279.         public Reactor.Async.Future Write (byte[] buffer) {
  280.             return this.Write(Reactor.Buffer.Create(buffer));
  281.         }
  282.  
  283.         /// <summary>
  284.         /// Writes this data to the stream.
  285.         /// </summary>
  286.         /// <param name="data"></param>
  287.         /// <returns>A future resolved when this write has completed.</returns>
  288.         public Reactor.Async.Future Write (string data) {
  289.             return this.Write(System.Text.Encoding.UTF8.GetBytes(data));
  290.         }
  291.  
  292.         /// <summary>
  293.         /// Writes this data to the stream.
  294.         /// </summary>
  295.         /// <param name="format"></param>
  296.         /// <param name="args"></param>
  297.         /// <returns>A future resolved when this write has completed.</returns>
  298.         public Reactor.Async.Future Write (string format, params object[] args) {
  299.             format = string.Format(format, args);
  300.             return this.Write(System.Text.Encoding.UTF8.GetBytes(format));
  301.         }
  302.  
  303.         /// <summary>
  304.         /// Writes this data to the stream.
  305.         /// </summary>
  306.         /// <param name="data"></param>
  307.         /// <returns>A future resolved when this write has completed.</returns>
  308.         public Reactor.Async.Future Write (byte data) {
  309.             return this.Write(new byte[1] { data });
  310.         }
  311.  
  312.         /// <summary>
  313.         /// Writes a System.Boolean value to the stream.
  314.         /// </summary>
  315.         /// <param name="value"></param>
  316.         /// <returns>A future resolved when this write has completed.</returns>
  317.         public Reactor.Async.Future Write (bool value) {
  318.             return this.Write(BitConverter.GetBytes(value));
  319.         }
  320.  
  321.         /// <summary>
  322.         /// Writes a System.Int16 value to the stream.
  323.         /// </summary>
  324.         /// <param name="value"></param>
  325.         /// <returns>A future resolved when this write has completed.</returns>
  326.         public Reactor.Async.Future Write (short value) {
  327.             return this.Write(BitConverter.GetBytes(value));
  328.         }
  329.  
  330.         /// <summary>
  331.         /// Writes a System.UInt16 value to the stream.
  332.         /// </summary>
  333.         /// <param name="value"></param>
  334.         /// <returns>A future resolved when this write has completed.</returns>
  335.         public Reactor.Async.Future Write (ushort value) {
  336.             return this.Write(BitConverter.GetBytes(value));
  337.         }
  338.  
  339.         /// <summary>
  340.         /// Writes a System.Int32 value to the stream.
  341.         /// </summary>
  342.         /// <param name="value"></param>
  343.         /// <returns>A future resolved when this write has completed.</returns>
  344.         public Reactor.Async.Future Write (int value) {
  345.             return this.Write(BitConverter.GetBytes(value));
  346.         }
  347.  
  348.         /// <summary>
  349.         /// Writes a System.UInt32 value to the stream.
  350.         /// </summary>
  351.         /// <param name="value"></param>
  352.         /// <returns>A future resolved when this write has completed.</returns>
  353.         public Reactor.Async.Future Write (uint value) {
  354.             return this.Write(BitConverter.GetBytes(value));
  355.         }
  356.  
  357.         /// <summary>
  358.         /// Writes a System.Int64 value to the stream.
  359.         /// </summary>
  360.         /// <param name="value"></param>
  361.         /// <returns>A future resolved when this write has completed.</returns>
  362.         public Reactor.Async.Future Write (long value) {
  363.             return this.Write(BitConverter.GetBytes(value));
  364.         }
  365.  
  366.         /// <summary>
  367.         /// Writes a System.UInt64 value to the stream.
  368.         /// </summary>
  369.         /// <param name="value"></param>
  370.         /// <returns>A future resolved when this write has completed.</returns>
  371.         public Reactor.Async.Future Write (ulong value) {
  372.             return this.Write(BitConverter.GetBytes(value));
  373.         }
  374.  
  375.         /// <summary>
  376.         /// Writes a System.Single value to the stream.
  377.         /// </summary>
  378.         /// <param name="value"></param>
  379.         /// <returns>A future resolved when this write has completed.</returns>
  380.         public Reactor.Async.Future Write (float value) {
  381.             return this.Write(BitConverter.GetBytes(value));
  382.         }
  383.  
  384.         /// <summary>
  385.         /// Writes a System.Double value to the stream.
  386.         /// </summary>
  387.         /// <param name="value"></param>
  388.         /// <returns>A future resolved when this write has completed.</returns>
  389.         public Reactor.Async.Future Write (double value) {
  390.             return this.Write(BitConverter.GetBytes(value));
  391.         }
  392.  
  393.         #endregion
  394.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement