Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #51 from teci/RemoveReferer

Merge with Ido
  • Loading branch information...
commit 930e8db995fbd0ea2019baa634cc74dff48716f9 2 parents 5253fb3 + 89e0f8f
@soitgoes authored
View
20 LoveSeat/CouchClient.cs
@@ -83,7 +83,7 @@ public CouchResponse TriggerReplication(string source, string target, bool conti
var options = new ReplicationOptions(source, target, continuous);
var response = request.Post()
.Data(options.ToString())
- .GetResponse();
+ .GetCouchResponse();
return response.GetJObject();
}
@@ -100,7 +100,7 @@ public CouchResponse TriggerReplication(string source, string target)
/// <returns></returns>
public CouchResponse CreateDatabase(string databaseName)
{
- return GetRequest(baseUri + databaseName).Put().GetResponse().GetJObject();
+ return GetRequest(baseUri + databaseName).Put().GetCouchResponse().GetJObject();
}
/// <summary>
/// Deletes the specified database
@@ -109,7 +109,7 @@ public CouchResponse CreateDatabase(string databaseName)
/// <returns></returns>
public CouchResponse DeleteDatabase(string databaseName)
{
- return GetRequest(baseUri + databaseName).Delete().GetResponse().GetJObject();
+ return GetRequest(baseUri + databaseName).Delete().GetCouchResponse().GetJObject();
}
/// <summary>
@@ -132,13 +132,13 @@ public CouchResponse CreateAdminUser(string usernameToCreate, string passwordToC
{
//Creates the user in the local.ini
var iniResult = GetRequest(baseUri + "_config/admins/" + HttpUtility.UrlEncode(usernameToCreate))
- .Put().Json().Data("\"" + passwordToCreate + "\"").GetResponse();
+ .Put().Json().Data("\"" + passwordToCreate + "\"").GetCouchResponse();
var user = @"{ ""name"": ""%name%"",
""_id"": ""org.couchdb.user:%name%"", ""type"": ""user"", ""roles"": [],
}".Replace("%name%", usernameToCreate).Replace("\r\n", "");
var docResult = GetRequest(baseUri + "_users/org.couchdb.user:" + HttpUtility.UrlEncode(usernameToCreate))
- .Put().Json().Data(user).GetResponse().GetJObject();
+ .Put().Json().Data(user).GetCouchResponse().GetJObject();
return docResult;
}
@@ -150,7 +150,7 @@ public CouchResponse CreateAdminUser(string usernameToCreate, string passwordToC
public void DeleteAdminUser(string userToDelete)
{
var iniResult = GetRequest(baseUri + "_config/admins/" + HttpUtility.UrlEncode(userToDelete))
- .Delete().Json().GetResponse();
+ .Delete().Json().GetCouchResponse();
var userDb = this.GetDatabase("_users");
var userId = "org.couchdb.user:" + HttpUtility.UrlEncode(userToDelete);
@@ -169,8 +169,8 @@ public void DeleteAdminUser(string userToDelete)
public bool HasDatabase(string databaseName) {
var request = GetRequest(baseUri + databaseName).Timeout(-1);
- var response = request.GetResponse();
- var pDocResult = new Document(response.GetResponseString());
+ var response = request.GetCouchResponse();
+ var pDocResult = new Document(response.ResponseString);
if (pDocResult["error"] == null) {
return (true);
@@ -238,7 +238,7 @@ public CouchResponse CreateUser(string usernameToCreate, string passwordToCreate
.Replace("\r\n", "");
var docResult = GetRequest(baseUri + "_users/org.couchdb.user:" + HttpUtility.UrlEncode(usernameToCreate))
- .Put().Json().Data(user).GetResponse();
+ .Put().Json().Data(user).GetCouchResponse();
if (docResult.StatusCode == HttpStatusCode.Created)
{
@@ -291,7 +291,7 @@ public UniqueIdentifiers GetUUID(int count)
}
var x = GetRequest(request);
- String str = x.Get().Json().GetResponse().GetJObject().ToString();
+ string str = x.Get().Json().GetCouchResponse().GetJObject().ToString();
UniqueIdentifiers y = Newtonsoft.Json.JsonConvert.DeserializeObject<UniqueIdentifiers>(str);
return y;
View
114 LoveSeat/CouchDatabase.cs
@@ -39,12 +39,12 @@ public CouchResponse CreateDocument(string id, string jsonForDocument)
var resp = GetRequest(databaseBaseUri + "/" + id)
.Put().Form()
.Data(jobj.ToString(Formatting.None))
- .GetResponse();
- return
+ .GetCouchResponse();
+ return
resp.GetJObject();
}
- public CouchResponse CreateDocument(IBaseObject doc)
+ public CouchResponse CreateDocument(IBaseObject doc)
{
var serialized = ObjectSerializer.Serialize(doc);
if (doc.Id != null)
@@ -61,15 +61,15 @@ public CouchResponse CreateDocument(IBaseObject doc)
public CouchResponse CreateDocument(string jsonForDocument)
{
var json = JObject.Parse(jsonForDocument); //to make sure it's valid json
- var jobj =
- GetRequest(databaseBaseUri + "/").Post().Json().Data(jsonForDocument).GetResponse().GetJObject();
+ var jobj =
+ GetRequest(databaseBaseUri + "/").Post().Json().Data(jsonForDocument).GetCouchResponse().GetJObject();
return jobj;
- }
+ }
public CouchResponse DeleteDocument(string id, string rev)
{
if (string.IsNullOrEmpty(id) || string.IsNullOrEmpty(rev))
throw new Exception("Both id and rev must have a value that is not empty");
- return GetRequest(databaseBaseUri + "/" + id + "?rev=" + rev).Delete().Form().GetResponse().GetJObject();
+ return GetRequest(databaseBaseUri + "/" + id + "?rev=" + rev).Delete().Form().GetCouchResponse().GetJObject();
}
/// <summary>
/// Returns null if document is not found
@@ -78,9 +78,9 @@ public CouchResponse DeleteDocument(string id, string rev)
/// <returns></returns>
public T GetDocument<T>(string id, bool attachments, IObjectSerializer objectSerializer)
{
- var resp = GetRequest(String.Format("{0}/{1}{2}", databaseBaseUri, id, attachments ? "?attachments=true" : string.Empty)).Get().Json().GetResponse();
+ var resp = GetRequest(String.Format("{0}/{1}{2}", databaseBaseUri, id, attachments ? "?attachments=true" : string.Empty)).Get().Json().GetCouchResponse();
if (resp.StatusCode == HttpStatusCode.NotFound) return default(T);
- return objectSerializer.Deserialize<T>(resp.GetResponseString());
+ return objectSerializer.Deserialize<T>(resp.ResponseString);
}
public T GetDocument<T>(string id, IObjectSerializer objectSerializer)
{
@@ -112,7 +112,8 @@ public T GetDocument<T>(Guid id)
}
public Document GetDocument(string id, bool attachments)
{
- var resp = GetRequest(String.Format("{0}/{1}{2}", databaseBaseUri, id, attachments ? "?attachments=true" : string.Empty)).Get().Json().GetResponse();
+ var resp = GetRequest(String.Format("{0}/{1}{2}", databaseBaseUri, id, attachments ? "?attachments=true" : string.Empty))
+ .Get().Json().GetCouchResponse();
if (resp.StatusCode == HttpStatusCode.NotFound) return null;
return resp.GetCouchDocument();
}
@@ -131,8 +132,13 @@ public ViewResult GetDocuments(Keys keyLst)
{
// serialize list of keys to json
string data = Newtonsoft.Json.JsonConvert.SerializeObject(keyLst);
- ViewOptions viewOptions = new ViewOptions { IncludeDocs = true };
- var resp = GetRequest(viewOptions, databaseBaseUri + "/_all_docs").Post().Json().Data(data).GetResponse();
+ ViewOptions viewOptions = new ViewOptions
+ {
+ IncludeDocs = true,
+ Keys = keyLst.Values.Select(x => new KeyOptions(x)).ToArray()
+ };
+
+ CouchWebResponse resp = GetRequest(viewOptions, databaseBaseUri + "/_all_docs").GetCouchResponse();
if (resp == null) return null;
@@ -142,7 +148,7 @@ public ViewResult GetDocuments(Keys keyLst)
return vw;
}
-
+
/// <summary>
/// Using the bulk API for the loading of documents.
/// </summary>
@@ -161,7 +167,7 @@ public BulkDocumentResponses SaveDocuments(Documents docs, bool all_or_nothing)
uri = uri + "?all_or_nothing=true";
}
- HttpWebResponse resp = GetRequest(uri).Post().Json().Data(data).GetResponse();
+ CouchWebResponse resp = GetRequest(uri).Post().Json().Data(data).GetCouchResponse();
if (resp == null)
{
@@ -170,19 +176,19 @@ public BulkDocumentResponses SaveDocuments(Documents docs, bool all_or_nothing)
if (resp.StatusCode != HttpStatusCode.Created)
{
- throw new System.Exception("Response returned with a HTTP status code of " + resp.StatusCode + " - " + resp.StatusDescription);
+ throw new System.Exception("Response returned with a HTTP status code of " + resp.StatusCode + " - " + resp.StatusDescription);
}
// Get response
- string x = resp.GetResponseString();
-
+ string x = resp.ResponseString;
+
// Convert to Bulk response
BulkDocumentResponses bulk = Newtonsoft.Json.JsonConvert.DeserializeObject<BulkDocumentResponses>(x);
return bulk;
}
-
+
/// <summary>
/// Adds an attachment to a document. If revision is not specified then the most recent will be fetched and used. Warning: if you need document update conflicts to occur please use the method that specifies the revision
/// </summary>
@@ -207,7 +213,7 @@ public CouchResponse AddAttachment(string id, byte[] attachment, string filename
public CouchResponse AddAttachment(string id, string rev, byte[] attachment, string filename, string contentType)
{
return
- GetRequest(string.Format("{0}/{1}/{2}?rev={3}", databaseBaseUri, id, filename, rev)).Put().ContentType(contentType).Data(attachment).GetResponse().GetJObject();
+ GetRequest(string.Format("{0}/{1}/{2}?rev={3}", databaseBaseUri, id, filename, rev)).Put().ContentType(contentType).Data(attachment).GetCouchResponse().GetJObject();
}
/// <summary>
/// Adds an attachment to a document. If revision is not specified then the most recent will be fetched and used. Warning: if you need document update conflicts to occur please use the method that specifies the revision
@@ -232,7 +238,7 @@ public CouchResponse AddAttachment(string id, Stream attachmentStream, string fi
public CouchResponse AddAttachment(string id, string rev, Stream attachmentStream, string filename, string contentType)
{
return
- GetRequest(string.Format("{0}/{1}/{2}?rev={3}", databaseBaseUri, id, filename, rev)).Put().ContentType(contentType).Data(attachmentStream).GetResponse().GetJObject();
+ GetRequest(string.Format("{0}/{1}/{2}?rev={3}", databaseBaseUri, id, filename, rev)).Put().ContentType(contentType).Data(attachmentStream).GetCouchResponse().GetJObject();
}
public Stream GetAttachmentStream(Document doc, string attachmentName)
@@ -241,7 +247,7 @@ public Stream GetAttachmentStream(Document doc, string attachmentName)
}
public Stream GetAttachmentStream(string docId, string rev, string attachmentName)
{
- return GetRequest(string.Format("{0}/{1}/{2}", databaseBaseUri, docId, HttpUtility.UrlEncode(attachmentName))).Get().GetResponse().GetResponseStream();
+ return GetRequest(string.Format("{0}/{1}/{2}", databaseBaseUri, docId, HttpUtility.UrlEncode(attachmentName))).Get().GetHttpResponse().GetResponseStream();
}
public Stream GetAttachmentStream(string docId, string attachmentName)
{
@@ -251,7 +257,7 @@ public Stream GetAttachmentStream(string docId, string attachmentName)
}
public CouchResponse DeleteAttachment(string id, string rev, string attachmentName)
{
- return GetRequest(string.Format("{0}/{1}/{2}?rev={3}", databaseBaseUri, id, attachmentName, rev)).Json().Delete().GetResponse().GetJObject();
+ return GetRequest(string.Format("{0}/{1}/{2}?rev={3}", databaseBaseUri, id, attachmentName, rev)).Json().Delete().GetCouchResponse().GetJObject();
}
public CouchResponse DeleteAttachment(string id, string attachmentName)
{
@@ -263,8 +269,8 @@ public CouchResponse SaveDocument(Document document)
{
if (document.Rev == null)
return CreateDocument(document);
-
- var resp = GetRequest(string.Format("{0}/{1}?rev={2}", databaseBaseUri, document.Id, document.Rev)).Put().Form().Data(document).GetResponse();
+
+ var resp = GetRequest(string.Format("{0}/{1}?rev={2}", databaseBaseUri, document.Id, document.Rev)).Put().Form().Data(document).GetCouchResponse();
return resp.GetJObject();
}
@@ -302,7 +308,7 @@ public ViewResult View(string viewName)
/// <returns>JSON success statement if the response code is Accepted</returns>
public JObject ViewCleanup()
{
- return CheckAccepted(GetRequest(databaseBaseUri + "/_view_cleanup").Post().Json().GetResponse());
+ return CheckAccepted(GetRequest(databaseBaseUri + "/_view_cleanup").Post().Json().GetCouchResponse());
}
/// <summary>
@@ -311,7 +317,7 @@ public JObject ViewCleanup()
/// <returns></returns>
public JObject Compact()
{
- return CheckAccepted(GetRequest(databaseBaseUri + "/_compact").Post().Json().GetResponse());
+ return CheckAccepted(GetRequest(databaseBaseUri + "/_compact").Post().Json().GetCouchResponse());
}
/// <summary>
@@ -322,16 +328,18 @@ public JObject Compact()
/// <remarks>Requires admin permissions.</remarks>
public JObject Compact(string designDoc)
{
- return CheckAccepted(GetRequest(databaseBaseUri + "/_compact/" + designDoc).Post().Json().GetResponse());
+ return CheckAccepted(GetRequest(databaseBaseUri + "/_compact/" + designDoc).Post().Json().GetCouchResponse());
}
- private static JObject CheckAccepted(HttpWebResponse resp)
+ private static JObject CheckAccepted(CouchWebResponse resp)
{
- if (resp == null) {
+ if (resp == null)
+ {
throw new System.Exception("Response returned null.");
}
- if (resp.StatusCode != HttpStatusCode.Accepted) {
+ if (resp.StatusCode != HttpStatusCode.Accepted)
+ {
throw new System.Exception(string.Format("Response return with a HTTP Code of {0} - {1}", resp.StatusCode, resp.StatusDescription));
}
@@ -340,10 +348,10 @@ private static JObject CheckAccepted(HttpWebResponse resp)
}
- public string Show (string showName, string docId)
+ public string Show(string showName, string docId)
{
ThrowDesignDocException();
- return Show(showName, docId, defaultDesignDoc);
+ return Show(showName, docId, defaultDesignDoc);
}
private void ThrowDesignDocException()
@@ -357,13 +365,13 @@ public string Show(string showName, string docId, string designDoc)
//TODO: add in Etag support for Shows
var uri = string.Format("{0}/_design/{1}/_show/{2}/{3}", databaseBaseUri, designDoc, showName, docId);
var req = GetRequest(uri);
- return req.GetResponse().GetResponseString();
+ return req.GetCouchResponse().ResponseString;
}
- public IListResult List(string listName, string viewName, ViewOptions options, string designDoc)
- {
- var uri = string.Format("{0}/_design/{1}/_list/{2}/{3}{4}", databaseBaseUri, designDoc, listName, viewName, options.ToString());
+ public IListResult List(string listName, string viewName, ViewOptions options, string designDoc)
+ {
+ var uri = string.Format("{0}/_design/{1}/_list/{2}/{3}{4}", databaseBaseUri, designDoc, listName, viewName, options.ToString());
var req = GetRequest(uri);
- return new ListResult(req.GetRequest(), req.GetResponse());
+ return new ListResult(req.GetRequest(), req.GetCouchResponse());
}
public IListResult List(string listName, string viewName, ViewOptions options)
@@ -377,12 +385,10 @@ public void SetDefaultDesignDoc(string designDoc)
this.defaultDesignDoc = designDoc;
}
- private ViewResult<T> ProcessGenericResults<T>(string uri, ViewOptions options) {
+ private ViewResult<T> ProcessGenericResults<T>(string uri, ViewOptions options)
+ {
CouchRequest req = GetRequest(options, uri);
- var resp = req.GetResponse();
- if (resp.StatusCode == HttpStatusCode.BadRequest) {
- throw new CouchException(req.GetRequest(), resp, resp.GetResponseString() + "\n" + req.GetRequest().RequestUri);
- }
+ CouchWebResponse resp = req.GetCouchResponse();
bool includeDocs = false;
if (options != null)
@@ -411,12 +417,12 @@ public ViewResult<T> View<T>(string viewName, ViewOptions options, string design
/// <param name="viewName"></param>
/// <param name="options"></param>
/// <returns></returns>
- public ViewResult<T> View<T>(string viewName, ViewOptions options)
+ public ViewResult<T> View<T>(string viewName, ViewOptions options)
{
ThrowDesignDocException();
- return View<T>(viewName, options, defaultDesignDoc);
+ return View<T>(viewName, options, defaultDesignDoc);
}
-
+
public ViewResult View(string viewName, ViewOptions options, string designDoc)
{
var uri = string.Format("{0}/_design/{1}/_view/{2}", databaseBaseUri, designDoc, viewName);
@@ -431,18 +437,20 @@ public ViewResult View(string viewName, ViewOptions options)
private ViewResult ProcessResults(string uri, ViewOptions options)
{
CouchRequest req = GetRequest(options, uri);
- var resp = req.GetResponse();
+ CouchWebResponse resp = req.GetCouchResponse();
return new ViewResult(resp, req.GetRequest());
}
-
+
private CouchRequest GetRequest(ViewOptions options, string uri)
{
if (options != null)
- uri += options.ToString();
+ uri += options.ToString();
CouchRequest request = GetRequest(uri, options == null ? null : options.Etag).Get().Json();
- if (options != null && options.Keys != null && options.Keys.Count() >= 100) {
- string keys = "{\"keys\": [" + String.Join(",", options.Keys.Select(k => k.ToRawString()).ToArray()) + "]}";
- request.Post().Data(keys);
+ if (options.isAtKeysSizeLimit)
+ {
+ // Encode the keys parameter in the request body and turn it into a POST request.
+ string keys = "{\"keys\": [" + String.Join(",", options.Keys.Select(k => k.ToRawString()).ToArray()) + "]}";
+ request.Post().Data(keys);
}
return request;
}
@@ -471,7 +479,7 @@ public SecurityDocument getSecurityConfiguration()
{
string request = databaseBaseUri + "/_security";
- var docResult = GetRequest(request).Get().Json().GetResponse().GetJObject();
+ var docResult = GetRequest(request).Get().Json().GetCouchResponse().GetJObject();
SecurityDocument sDoc = Newtonsoft.Json.JsonConvert.DeserializeObject<SecurityDocument>(docResult.ToString());
@@ -489,7 +497,7 @@ public void UpdateSecurityDocument(SecurityDocument sDoc)
// serialize SecurityDocument to json
string data = Newtonsoft.Json.JsonConvert.SerializeObject(sDoc);
- var result = GetRequest(request).Put().Json().Data(data).GetResponse();
+ var result = GetRequest(request).Put().Json().Data(data).GetCouchResponse();
if (result.StatusCode != HttpStatusCode.OK) //Check if okay
{
View
6 LoveSeat/CouchException.cs
@@ -1,4 +1,5 @@
using System.Net;
+using LoveSeat.Support;
namespace LoveSeat
{
@@ -13,6 +14,11 @@ public CouchException(HttpWebRequest request, HttpWebResponse response, string m
this.response = response;
}
+ public CouchException(HttpWebRequest request, CouchWebResponse response, string mesg)
+ : base(mesg)
+ {
+ }
+
public HttpWebRequest Request { get { return request; } }
public HttpWebResponse Response { get { return response; } }
}
View
2  LoveSeat/CouchResponse.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Net;
using System.Text;
using Newtonsoft.Json.Linq;
@@ -9,6 +10,7 @@ public class CouchResponse : JObject {
public CouchResponse(JObject obj) : base(obj)
{
}
+
public int StatusCode { get; set; }
}
}
View
5 LoveSeat/Interfaces/IListResult.cs
@@ -8,10 +8,7 @@ public interface IListResult: System.IEquatable<IListResult>
/// Typically won't be needed Provided for debuging assitance
/// </summary>
HttpWebRequest Request { get; }
- /// <summary>
- /// Typically won't be needed Provided for debuging assitance
- /// </summary>
- HttpWebResponse Response { get; }
+
HttpStatusCode StatusCode { get; }
string Etag { get; }
string RawString { get; }
View
15 LoveSeat/ListResult.cs
@@ -8,9 +8,9 @@ namespace LoveSeat
public class ListResult : IListResult
{
private readonly HttpWebRequest request;
- private readonly HttpWebResponse response;
+ private readonly CouchWebResponse response;
- public ListResult(HttpWebRequest request , HttpWebResponse response)
+ public ListResult(HttpWebRequest request, CouchWebResponse response)
{
this.request = request;
this.response = response;
@@ -21,24 +21,19 @@ public HttpWebRequest Request
get { return request; }
}
- public HttpWebResponse Response
- {
- get { return response; }
- }
-
public HttpStatusCode StatusCode
{
- get { return Response.StatusCode; }
+ get { return response.StatusCode; }
}
public string Etag
{
- get { return Response.Headers["ETag"]; }
+ get { return response.ETag; }
}
public string RawString
{
- get { return Response.GetResponseString(); }
+ get { return response.ResponseString; }
}
public bool Equals(IListResult other)
View
1  LoveSeat/LoveSeat.csproj
@@ -84,6 +84,7 @@
<Compile Include="CouchDatabase.cs" />
<Compile Include="Support\CouchRequest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Support\CouchWebResponse.cs" />
<Compile Include="Support\NullableDictionary.cs" />
<Compile Include="Support\ReplicationOptions.cs" />
<Compile Include="Support\ResponseExtensionMethods.cs" />
View
2  LoveSeat/Properties/AssemblyInfo.cs
@@ -33,4 +33,4 @@
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.1")]
+[assembly: AssemblyFileVersion("1.0.1.1")]
View
23 LoveSeat/Support/CouchBase.cs
@@ -31,7 +31,7 @@ public static bool Authenticate(string baseUri, string userName, string password
.ContentType("application/x-www-form-urlencoded")
.Data("name=" + userName + "&password=" + password)
.Timeout(3000)
- .GetResponse();
+ .GetCouchResponse();
return response.StatusCode == HttpStatusCode.OK;
}
public Cookie GetSession() {
@@ -43,19 +43,22 @@ public static bool Authenticate(string baseUri, string userName, string password
if (string.IsNullOrEmpty(username)) return null;
var request = new CouchRequest(baseUri + "_session");
request.GetRequest().Headers.Add("Authorization:Basic " + Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(username + ":" + password)));
- var response = request.Post()
+ using (HttpWebResponse response = request.Post()
.Form()
.Data("name=" + username + "&password=" + password)
- .GetResponse();
+ .GetHttpResponse())
+ {
- var header = response.Headers.Get("Set-Cookie");
- if (header != null) {
- var parts = header.Split(';')[0].Split('=');
- authCookie = new Cookie(parts[0], parts[1]);
- authCookie.Domain = response.Server;
- cookiestore.Add("authcookie", authCookie, TimeSpan.FromMinutes(9));
+ var header = response.Headers.Get("Set-Cookie");
+ if (header != null)
+ {
+ var parts = header.Split(';')[0].Split('=');
+ authCookie = new Cookie(parts[0], parts[1]);
+ authCookie.Domain = response.Server;
+ cookiestore.Add("authcookie", authCookie, TimeSpan.FromMinutes(9));
+ }
+ return authCookie;
}
- return authCookie;
}
public void SetTimeout(int timeoutMs)
View
135 LoveSeat/Support/CouchRequest.cs
@@ -4,15 +4,18 @@
using System.Web;
using Newtonsoft.Json.Linq;
-namespace LoveSeat.Support {
- public class CouchRequest {
+namespace LoveSeat.Support
+{
+ public class CouchRequest
+ {
private const string INVALID_USERNAME_OR_PASSWORD = "reason=Name or password is incorrect";
private const string NOT_AUTHORIZED = "reason=You are not authorized to access this db.";
private const int STREAM_BUFFER_SIZE = 4096;
private readonly HttpWebRequest request;
public CouchRequest(string uri)
- : this(uri, new Cookie(), null) {
+ : this(uri, new Cookie(), null)
+ {
}
/// <summary>
@@ -21,7 +24,8 @@ public CouchRequest(string uri)
/// <param name="uri"></param>
/// <param name="authCookie"></param>
/// <param name="eTag"></param>
- public CouchRequest(string uri, Cookie authCookie, string eTag) {
+ public CouchRequest(string uri, Cookie authCookie, string eTag)
+ {
request = (HttpWebRequest)WebRequest.Create(uri);
request.Headers.Clear(); //important
if (!string.IsNullOrEmpty(eTag))
@@ -43,13 +47,15 @@ public CouchRequest(string uri)
/// <param name="uri"></param>
/// <param name="username"></param>
/// <param name="password"></param>
- public CouchRequest(string uri, string username, string password) {
+ public CouchRequest(string uri, string username, string password)
+ {
request = (HttpWebRequest)WebRequest.Create(uri);
request.Headers.Clear(); //important
// Deal with Authorization Header
- if (username != null) {
+ if (username != null)
+ {
string authValue = "Basic ";
string userNAndPassword = username + ":" + password;
@@ -63,27 +69,30 @@ public CouchRequest(string uri)
request.Headers.Add("Accept-Charset", "utf-8");
request.Headers.Add("Accept-Language", "en-us");
- request.Referer = uri;
request.ContentType = "application/json";
request.KeepAlive = true;
request.Timeout = 10000;
}
- public CouchRequest Put() {
+ public CouchRequest Put()
+ {
request.Method = "PUT";
return this;
}
- public CouchRequest Get() {
+ public CouchRequest Get()
+ {
request.Method = "GET";
return this;
}
- public CouchRequest Post() {
+ public CouchRequest Post()
+ {
request.Method = "POST";
return this;
}
- public CouchRequest Delete() {
+ public CouchRequest Delete()
+ {
request.Method = "DELETE";
return this;
}
@@ -95,70 +104,122 @@ public CouchRequest Data(Stream data)
var bytesRead = 0;
while (0 != (bytesRead = data.Read(buffer, 0, buffer.Length)))
{
- body.Write(buffer, 0, bytesRead);
+ body.Write(buffer, 0, bytesRead);
}
}
return this;
}
- public CouchRequest Data(string data) {
- using (var body = request.GetRequestStream()) {
+ public CouchRequest Data(string data)
+ {
+ using (var body = request.GetRequestStream())
+ {
var encodedData = Encoding.UTF8.GetBytes(data);
body.Write(encodedData, 0, encodedData.Length);
}
return this;
}
- public CouchRequest Data(byte[] attachment) {
- using (var body = request.GetRequestStream()) {
+ public CouchRequest Data(byte[] attachment)
+ {
+ using (var body = request.GetRequestStream())
+ {
body.Write(attachment, 0, attachment.Length);
}
return this;
}
- public CouchRequest Data(JObject obj) {
+ public CouchRequest Data(JObject obj)
+ {
return Data(obj.ToString());
}
- public CouchRequest ContentType(string contentType) {
+ public CouchRequest ContentType(string contentType)
+ {
request.ContentType = contentType;
return this;
}
- public CouchRequest Form() {
+ public CouchRequest Form()
+ {
request.ContentType = "application/x-www-form-urlencoded";
return this;
}
- public CouchRequest Json() {
+ public CouchRequest Json()
+ {
request.ContentType = "application/json";
return this;
}
- public CouchRequest Timeout(int timeoutMs) {
+ public CouchRequest Timeout(int timeoutMs)
+ {
request.Timeout = timeoutMs;
return this;
}
- public HttpWebRequest GetRequest() {
+ public HttpWebRequest GetRequest()
+ {
return request;
}
- public HttpWebResponse GetResponse() {
+ public CouchWebResponse GetCouchResponse()
+ {
+ bool failedAuth = false;
+ try
+ {
+ using (var response = (HttpWebResponse)request.GetResponse())
+ {
+ string msg = "";
+ if (isAuthenticateOrAuthorized(response, ref msg) == false)
+ {
+ failedAuth = true;
+ throw new WebException(msg);
+ }
+
+ if (response.StatusCode == HttpStatusCode.BadRequest)
+ {
+ throw new CouchException(request, response, response.GetResponseString() + "\n" + request.RequestUri);
+ }
+
+ return new CouchWebResponse(response);
+ }
+ }
+ catch (WebException webEx)
+ {
+ if (failedAuth == true)
+ {
+ throw;
+ }
+ var response = (HttpWebResponse)webEx.Response;
+ if (response == null)
+ throw new HttpException("Request failed to receive a response", webEx);
+ return new CouchWebResponse(response);
+ }
+ throw new HttpException("Request failed to receive a response");
+ }
+
+ public HttpWebResponse GetHttpResponse()
+ {
bool failedAuth = false;
- try {
+ try
+ {
var response = (HttpWebResponse)request.GetResponse();
string msg = "";
- if (isAuthenticateOrAuthorized(response, ref msg) == false) {
+ if (isAuthenticateOrAuthorized(response, ref msg) == false)
+ {
failedAuth = true;
throw new WebException(msg, new System.Exception(msg));
}
return response;
- } catch (WebException webEx) {
- if (failedAuth == true) {
- throw webEx;
+ }
+ catch (WebException webEx)
+ {
+ if (failedAuth == true)
+ {
+ throw;
}
var response = (HttpWebResponse)webEx.Response;
if (response == null)
- throw new HttpException("Request failed to receive a response");
+ throw new HttpException("Request failed to receive a response", webEx);
return response;
}
throw new HttpException("Request failed to receive a response");
@@ -169,19 +230,25 @@ public CouchRequest Data(Stream data)
/// Checks response if username and password was valid
/// </summary>
/// <param name="response"></param>
- private bool isAuthenticateOrAuthorized(HttpWebResponse response, ref string message) {
+ private bool isAuthenticateOrAuthorized(HttpWebResponse response, ref string message)
+ {
//"reason=Name or password is incorrect"
// Check if query string is okay
string[] split = response.ResponseUri.Query.Split('&');
- if (split.Length > 0) {
- for (int i = 0; i < split.Length; i++) {
+ if (split.Length > 0)
+ {
+ for (int i = 0; i < split.Length; i++)
+ {
string temp = System.Web.HttpUtility.UrlDecode(split[i]);
- if (temp.Contains(INVALID_USERNAME_OR_PASSWORD) == true) {
+ if (temp.Contains(INVALID_USERNAME_OR_PASSWORD) == true)
+ {
message = "Invalid username or password";
return false;
- } else if (temp.Contains(NOT_AUTHORIZED) == true) {
+ }
+ else if (temp.Contains(NOT_AUTHORIZED) == true)
+ {
message = "Not Authorized to access database";
return false;
}
View
46 LoveSeat/Support/CouchWebResponse.cs
@@ -0,0 +1,46 @@
+using System.Net;
+using Newtonsoft.Json.Linq;
+
+namespace LoveSeat.Support
+{
+ /// <summary>
+ /// Repersent a web response from CouchDB database.
+ /// </summary>
+ public class CouchWebResponse
+ {
+ private readonly string responseString;
+ private readonly HttpStatusCode statusCode;
+ private readonly string statusDescription;
+ private readonly string etag;
+
+ public CouchWebResponse(HttpWebResponse response)
+ {
+ responseString = response.GetResponseString();
+ statusCode = response.StatusCode;
+ statusDescription = response.StatusDescription;
+ etag = response.Headers["ETag"];
+ }
+
+ public string ResponseString { get { return responseString; } }
+
+ public HttpStatusCode StatusCode { get { return statusCode; } }
+
+ public string StatusDescription { get { return statusDescription; } }
+
+ public string ETag { get { return etag; } }
+
+ public CouchResponse GetJObject()
+ {
+ var resp = new CouchResponse(JObject.Parse(responseString));
+ resp.StatusCode = (int)statusCode;
+ return resp;
+ }
+
+ public Document GetCouchDocument()
+ {
+ var jobj = JObject.Parse(responseString);
+ return new Document(jobj);
+ }
+
+ }
+}
View
19 LoveSeat/ViewOptions.cs
@@ -11,6 +11,11 @@ namespace LoveSeat
{
public class ViewOptions : IViewOptions
{
+ /// <summary>
+ /// Limit the length of the Keys parameter to 1800 characters.
+ /// </summary>
+ private const int KeysLengthLimit = 1800;
+
public ViewOptions()
{
Key = new KeyOptions();
@@ -47,10 +52,10 @@ public ViewOptions()
public override string ToString()
{
- string result = "";
+ string result = "";
if ((Key != null) && (Key.Count > 0))
result += "&key=" + Key.ToString();
- if (Keys != null && Keys.Count() < 100)
+ if (Keys != null && !isAtKeysSizeLimit)
result += "&keys=[" + String.Join(",", Keys.Select(k => k.ToString()).ToArray()) + "]";
if ((StartKey != null) && (StartKey.Count > 0))
if((StartKey.Count == 1) && (EndKey.Count > 1))
@@ -96,6 +101,16 @@ public override string ToString()
if (!string.IsNullOrEmpty(EndKeyDocId))
result += "&endkey_docid=" + EndKeyDocId;
return result.Length < 1 ? "" : "?" + result.Substring(1);
+ }
+
+ /// <summary>
+ /// Get indication if the length of keys parameter went over the allowed limit.
+ /// This indicate that the Keys parameter should be encoded in the requeqst body
+ /// instead of URL paraemter.
+ /// </summary>
+ internal bool isAtKeysSizeLimit
+ {
+ get { return Keys != null && Keys.Any() && Keys.ToString().Length > KeysLengthLimit; }
}
}
View
27 LoveSeat/ViewResult.cs
@@ -14,7 +14,7 @@ public class ViewResult<T> : ViewResult
{
private readonly IObjectSerializer objectSerializer = null;
private CouchDictionary<T> dict = null;
- public ViewResult(HttpWebResponse response, HttpWebRequest request, IObjectSerializer objectSerializer, bool includeDocs = false)
+ public ViewResult(CouchWebResponse response, HttpWebRequest request, IObjectSerializer objectSerializer, bool includeDocs = false)
: base(response, request, includeDocs)
{
this.objectSerializer = objectSerializer;
@@ -52,30 +52,25 @@ public IEnumerable<T> Items
public class ViewResult : IViewResult
{
- private readonly HttpWebResponse response;
+ private readonly CouchWebResponse response;
private readonly HttpWebRequest request;
private JObject json = null;
- private readonly string responseString;
- public JObject Json { get { return json ?? (json = JObject.Parse(responseString)); } }
- public ViewResult(HttpWebResponse response, HttpWebRequest request, bool includeDocs = false)
+ public JObject Json { get { return json ?? (json = JObject.Parse(response.ResponseString)); } }
+ public ViewResult(CouchWebResponse response, HttpWebRequest request, bool includeDocs = false)
{
this.response = response;
this.request = request;
- this.responseString = response.GetResponseString();
this.IncludeDocs = includeDocs;
}
/// <summary>
/// Typically won't be needed. Provided for debuging assistance
/// </summary>
public HttpWebRequest Request { get { return request; } }
- /// <summary>
- /// Typically won't be needed. Provided for debugging assistance
- /// </summary>
- public HttpWebResponse Response { get { return response; } }
+
public HttpStatusCode StatusCode { get { return response.StatusCode; } }
- public string Etag { get { return response.Headers["ETag"]; } }
+ public string Etag { get { return response.ETag; } }
public int TotalRows
{
get
@@ -151,7 +146,7 @@ public IEnumerable<string> RawDocs
}
public string RawString
{
- get { return responseString; }
+ get { return response.ResponseString; }
}
public bool Equals(IListResult other)
@@ -162,11 +157,17 @@ public bool Equals(IListResult other)
public override string ToString()
{
- return responseString;
+ return response.ResponseString;
}
/// <summary>
/// Provides a formatted version of the json returned from this Result. (Avoid this method in favor of RawString as it's much more performant)
/// </summary>
public string FormattedResponse { get { return Json.ToString(Formatting.Indented); } }
+
+ public HttpWebResponse Response
+ {
+ get { throw new NotImplementedException(); }
+ }
+
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.