The Author say:
It's written in C#, it has been carefully designed to be true to the protocol it implements, get out of your way, and not tell you how to live. It is easy to integrate into a variety of applications, and is an excellent choice for creating interactive websites and web APIs. Whether your coming from ASP.NET, PHP, Django, or elsewhere, you’ll find Kayak to be refreshingly simple to use.
http://kayakhttp.com/
especially i liked the extensions to read / write http
using System;
using System.IO;
using System.Text;
namespace Kayak
{
struct HttpRequestLine
{
public string Verb;
public string RequestUri;
public string HttpVersion;
}
struct HttpStatusLine
{
public string HttpVersion;
public int StatusCode;
public string ReasonPhrase;
}
/// <summary>
/// A collection of extension methods to help speak HTTP.
/// </summary>
static class HttpExtensions
{
/// <summary>
/// Parses the first line of an incoming HTTP request.
/// </summary>
public static HttpRequestLine ReadHttpRequestLine(this Stream stream)
{
string statusLine = stream.ReadLine(Encoding.ASCII, 1024 * 4);
if (string.IsNullOrEmpty(statusLine))
throw new Exception("Could not parse request status.");
int firstSpace = statusLine.IndexOf(' ');
int lastSpace = statusLine.LastIndexOf(' ');
if (firstSpace == -1 || lastSpace == -1)
throw new Exception("Could not parse request status.");
var requestLine = new HttpRequestLine();
requestLine.Verb = statusLine.Substring(0, firstSpace);
bool hasVersion = lastSpace != firstSpace;
if (hasVersion)
requestLine.HttpVersion = statusLine.Substring(lastSpace + 1);
else
requestLine.HttpVersion = "HTTP/1.0";
requestLine.RequestUri = hasVersion
? statusLine.Substring(firstSpace + 1, lastSpace - firstSpace - 1)
: statusLine.Substring(firstSpace + 1);
return requestLine;
}
/// <summary>
/// Parses a list of HTTP request headers, terminated by an empty line.
/// </summary>
public static NameValueDictionary ReadHttpHeaders(this Stream stream)
{
var headers = new NameValueDictionary();
string line = null;
while (!string.IsNullOrEmpty(line = stream.ReadLine(Encoding.ASCII, 1024 * 4)))
{
int colon = line.IndexOf(':');
headers.Add(line.Substring(0, colon), line.Substring(colon + 1).Trim());
}
headers.BecomeReadOnly();
return headers;
}
public static void WriteHttpStatusLine(this Stream stream,
HttpStatusLine statusLine)
{
// e.g. HTTP/1.0 200 OK
string line = string.Format("{0} {1} {2}\r\n", statusLine.HttpVersion, statusLine.StatusCode, statusLine.ReasonPhrase);
byte[] statusBytes = Encoding.ASCII.GetBytes(line);
stream.Write(statusBytes, 0, statusBytes.Length);
}
public static void WriteHttpHeaders(this Stream stream, NameValueDictionary headers)
{
using (StreamWriter writer = new StreamWriter(stream, Encoding.ASCII))
{
writer.NewLine = "\r\n";
foreach (NameValuePair pair in headers)
foreach (string value in pair.Values)
writer.WriteLine("{0}: {1}", pair.Name, value);
writer.WriteLine();
writer.Flush();
}
}
}
}
some cool cookie extensions are also available:
using System.Text;
using System.Web;
namespace Kayak
{
static class CookieExtensions
{
public static HttpCookieCollection ParseAsCookieHeader(this string cookies)
{
var coll = new HttpCookieCollection();
if (!string.IsNullOrEmpty(cookies))
foreach (string cookie in cookies.Split(';'))
{
int index = cookie.IndexOf('=');
if (index >= 0)
coll.Add(new HttpCookie(cookie.Substring(0, index).Trim(), cookie.Substring(index + 1)));
}
return coll;
}
public static void CopyToHeaderDictionary(this HttpCookieCollection cookies,
NameValueDictionary headers)
{
foreach (string name in cookies)
headers.Add("Set-Cookie", cookies[name].ToSetCookieHeader());
}
public static string ToSetCookieHeader(this HttpCookie cookie)
{
var sb = new StringBuilder()
.Append(cookie.Name)
.Append('=')
.Append(cookie.Value);
if (cookie.Domain != null)
sb.Append("; domain=").Append(cookie.Domain);
if (cookie.Path != null)
sb.Append("; path=").Append(cookie.Path);
sb.Append("; expires=").Append(cookie.Expires.ToUniversalTime().ToString("r"));
if (cookie.Secure)
sb.Append("; secure");
if (cookie.HttpOnly)
sb.Append("; HttpOnly");
return sb.ToString();
}
}
}
No comments:
Post a Comment