PageRenderTime 53ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/agsxmpp/agsxmpp/protocol/client/Error.cs

https://bitbucket.org/ipre/calico
C# | 593 lines | 293 code | 48 blank | 252 comment | 46 complexity | 311a5d081f2267a7e4c5af3d425eb8d3 MD5 | raw file
Possible License(s): LGPL-2.1, LGPL-3.0, GPL-2.0, GPL-3.0, LGPL-2.0
  1. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2. * Copyright (c) 2003-2010 by AG-Software *
  3. * All Rights Reserved. *
  4. * Contact information for AG-Software is available at http://www.ag-software.de *
  5. * *
  6. * Licence: *
  7. * The agsXMPP SDK is released under a dual licence *
  8. * agsXMPP can be used under either of two licences *
  9. * *
  10. * A commercial licence which is probably the most appropriate for commercial *
  11. * corporate use and closed source projects. *
  12. * *
  13. * The GNU Public License (GPL) is probably most appropriate for inclusion in *
  14. * other open source projects. *
  15. * *
  16. * See README.html for details. *
  17. * *
  18. * For general enquiries visit our website at: *
  19. * http://www.ag-software.de *
  20. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  21. using System;
  22. using agsXMPP.Xml.Dom;
  23. // JEP-0086: Error Condition Mappings
  24. // <stanza-kind to='sender' type='error'>
  25. // [RECOMMENDED to include sender XML here]
  26. // <error type='error-type'>
  27. // <defined-condition xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  28. // <text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'
  29. // xml:lang='langcode'>
  30. // OPTIONAL descriptive text
  31. // </text>
  32. // [OPTIONAL application-specific condition element]
  33. // </error>
  34. // </stanza-kind>
  35. // Legacy Error
  36. // <error code="501">Not Implemented</error>
  37. // XMPP Style Error
  38. // <error code='404' type='cancel'>
  39. // <item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  40. // </error>
  41. namespace agsXMPP.protocol.client
  42. {
  43. // XMPP error condition XMPP error type Legacy error code
  44. // <bad-request/> modify 400
  45. // <conflict/> cancel 409
  46. // <feature-not-implemented/> cancel 501
  47. // <forbidden/> auth 403
  48. // <gone/> modify 302 (permanent)
  49. // <internal-server-error/> wait 500
  50. // <item-not-found/> cancel 404
  51. // <jid-malformed/> modify 400
  52. // <not-acceptable/> modify 406
  53. // <not-allowed/> cancel 405
  54. // <not-authorized/> auth 401
  55. // <payment-required/> auth 402
  56. // <recipient-unavailable/> wait 404
  57. // <redirect/> modify 302 (temporary)
  58. // <registration-required/> auth 407
  59. // <remote-server-not-found/> cancel 404
  60. // <remote-server-timeout/> wait 504
  61. // <resource-constraint/> wait 500
  62. // <service-unavailable/> cancel 503
  63. // <subscription-required/> auth 407
  64. // <undefined-condition/> [any] 500
  65. // <unexpected-request/> wait 400
  66. /// <summary>
  67. /// stanza error condition as defined in RFC 3920 9.3
  68. /// </summary>
  69. public enum ErrorCondition
  70. {
  71. /// <summary>
  72. /// The sender has sent a stanza containing XML that does not conform to the appropriate schema or that
  73. /// cannot be processed (e.g., an IQ stanza that includes an unrecognized value of the 'type' attribute);
  74. /// the associated error type SHOULD be "modify".
  75. /// </summary>
  76. BadRequest,
  77. /// <summary>
  78. /// Access cannot be granted because an existing resource exists with the same name or address;
  79. /// the associated error type SHOULD be "cancel".
  80. /// </summary>
  81. Conflict,
  82. /// <summary>
  83. /// The feature represented in the XML stanza is not implemented by the intended recipient or
  84. /// an intermediate server and therefore the stanza cannot be processed; the associated error type SHOULD
  85. /// be "cancel" or "modify".
  86. /// </summary>
  87. FeatureNotImplemented,
  88. /// <summary>
  89. /// The requesting entity does not possess the required permissions to perform the action;
  90. /// the associated error type SHOULD be "auth".
  91. /// </summary>
  92. Forbidden,
  93. /// <summary>
  94. /// The recipient or server can no longer be contacted at this address
  95. /// (the error stanza MAY contain a new address in the XML character data of the &lt;gone/&gt; element);
  96. /// the associated error type SHOULD be "cancel" or "modify".
  97. /// </summary>
  98. Gone,
  99. /// <summary>
  100. /// The server could not process the stanza because of a misconfiguration or an otherwise-undefined
  101. /// internal server error; the associated error type SHOULD be "wait" or "cancel".
  102. /// </summary>
  103. InternalServerError,
  104. /// <summary>
  105. /// The addressed JID or item requested cannot be found; the associated error type SHOULD be "cancel" or "modify".
  106. /// </summary>
  107. /// <remarks>
  108. /// An application MUST NOT return this error if doing so would provide information about the intended
  109. /// recipient's network availability to an entity that is not authorized to know such information;
  110. /// instead it SHOULD return a &lt;service-unavailable/&gt; error.
  111. /// </remarks>
  112. ItemNotFound,
  113. /// <summary>
  114. /// The sending entity has provided or communicated an XMPP address
  115. /// (e.g., a value of the 'to' attribute) or aspect thereof (e.g., an XMPP resource identifier)
  116. /// that does not adhere to the syntax defined under RFC3920 Section 3 (Addresses);
  117. /// the associated error type SHOULD be "modify".
  118. /// </summary>
  119. JidMalformed,
  120. /// <summary>
  121. /// The recipient or server understands the request but is refusing to process it because it does not
  122. /// meet criteria defined by the recipient or server (e.g., a local policy regarding stanza size
  123. /// limits or acceptable words in messages); the associated error type SHOULD be "modify".
  124. /// </summary>
  125. NotAcceptable,
  126. /// <summary>
  127. /// The recipient or server does not allow any entity to perform the action (e.g., sending to entities at
  128. /// a blacklisted domain); the associated error type SHOULD be "cancel".
  129. /// </summary>
  130. NotAllowed,
  131. /// <summary>
  132. /// The sender must provide proper credentials before being allowed to perform the action, or has provided
  133. /// improper credentials; the associated error type SHOULD be "auth".
  134. /// </summary>
  135. NotAuthorized,
  136. /// <summary>
  137. /// The item requested has not changed since it was last requested; the associated error type SHOULD be "continue".
  138. /// </summary>
  139. NotModified,
  140. /// <summary>
  141. /// The requesting entity is not authorized to access the requested service because payment is required;
  142. /// the associated error type SHOULD be "auth".
  143. /// </summary>
  144. PaymentRequired,
  145. /// <summary>
  146. /// The intended recipient is temporarily unavailable; the associated error type SHOULD be "wait".
  147. /// </summary>
  148. /// <remarks>
  149. /// An application MUST NOT return this error if doing so would provide information about the
  150. /// intended recipient's network availability to an entity that is not authorized to know such
  151. /// information; instead it SHOULD return a &lt;service-unavailable/&gt; error.
  152. /// </remarks>
  153. RecipientUnavailable,
  154. /// <summary>
  155. /// The recipient or server is redirecting requests for this information to another entity,
  156. /// typically in a temporary fashion; the associated error type SHOULD be "modify" and the error stanza
  157. /// SHOULD contain the alternate address (which SHOULD be a valid JID) in the XML character data
  158. /// of the &lt;redirect/&gt; element.
  159. /// </summary>
  160. Redirect,
  161. /// <summary>
  162. /// The requesting entity is not authorized to access the requested service because prior
  163. /// registration is required; the associated error type SHOULD be &quot;auth&quot;.
  164. /// </summary>
  165. RegistrationRequired,
  166. /// <summary>
  167. /// A remote server or service specified as part or all of the JID of the intended recipient
  168. /// does not exist; the associated error type SHOULD be &quot;cancel&quot;.
  169. /// </summary>
  170. RemoteServerNotFound,
  171. /// <summary>
  172. /// A remote server or service specified as part or all of the JID of the intended recipient
  173. /// (or required to fulfill a request) could not be contacted within a reasonable amount
  174. /// of time; the associated error type SHOULD be &quot;wait&quot;.
  175. /// </summary>
  176. RemoteServerTimeout,
  177. /// <summary>
  178. /// The server or recipient lacks the system resources necessary to service the request;
  179. /// the associated error type SHOULD be "wait".
  180. /// </summary>
  181. ResourceConstraint,
  182. /// <summary>
  183. /// The server or recipient does not currently provide the requested service;
  184. /// the associated error type SHOULD be &quot;cancel&quot;.
  185. /// </summary>
  186. /// <remarks>
  187. /// An application SHOULD return a &lt;service-unavailable/&gt; error instead of
  188. /// &lt;item-not-found/&gt; or &lt;recipient-unavailable/&gt; if sending one of the latter
  189. /// errors would provide information about the intended recipient&#39;s network
  190. /// availability to an entity that is not authorized to know such information.
  191. /// </remarks>
  192. ServiceUnavailable,
  193. /// <summary>
  194. /// The requesting entity is not authorized to access the requested service
  195. /// because a prior subscription is required; the associated error type SHOULD be &quot;auth&quot;.
  196. /// </summary>
  197. SubscriptionRequired,
  198. /// <summary>
  199. /// The error condition is not one of those defined by the other conditions in this list;
  200. /// any error type may be associated with this condition, and it SHOULD be used only in conjunction
  201. /// with an application-specific condition.
  202. /// </summary>
  203. UndefinedCondition,
  204. /// <summary>
  205. /// The recipient or server understood the request but was not expecting it at this time
  206. /// (e.g., the request was out of order); the associated error type SHOULD be "wait" or "modify".
  207. /// </summary>
  208. UnexpectedRequest
  209. }
  210. // The value of the <error/> element's 'type' attribute MUST be one of the following:
  211. // * cancel -- do not retry (the error is unrecoverable)
  212. // * continue -- proceed (the condition was only a warning)
  213. // * modify -- retry after changing the data sent
  214. // * auth -- retry after providing credentials
  215. // * wait -- retry after waiting (the error is temporary)
  216. public enum ErrorType
  217. {
  218. cancel,
  219. @continue,
  220. modify,
  221. auth,
  222. wait
  223. }
  224. /// <summary>
  225. /// The legacy Error Code
  226. /// </summary>
  227. public enum ErrorCode
  228. {
  229. /// <summary>
  230. /// Bad request
  231. /// </summary>
  232. BadRequest = 400,
  233. /// <summary>
  234. /// Unauthorized
  235. /// </summary>
  236. Unauthorized = 401,
  237. /// <summary>
  238. /// Payment required
  239. /// </summary>
  240. PaymentRequired = 402,
  241. /// <summary>
  242. /// Forbidden
  243. /// </summary>
  244. Forbidden = 403,
  245. /// <summary>
  246. /// Not found
  247. /// </summary>
  248. NotFound = 404,
  249. /// <summary>
  250. /// Not allowed
  251. /// </summary>
  252. NotAllowed = 405,
  253. /// <summary>
  254. /// Not acceptable
  255. /// </summary>
  256. NotAcceptable = 406,
  257. /// <summary>
  258. /// Registration required
  259. /// </summary>
  260. RegistrationRequired = 407,
  261. /// <summary>
  262. /// Request timeout
  263. /// </summary>
  264. RequestTimeout = 408,
  265. /// <summary>
  266. /// Conflict
  267. /// </summary>
  268. Conflict = 409,
  269. /// <summary>
  270. /// Internal server error
  271. /// </summary>
  272. InternalServerError = 500,
  273. /// <summary>
  274. /// Not implemented
  275. /// </summary>
  276. NotImplemented = 501,
  277. /// <summary>
  278. /// Remote server error
  279. /// </summary>
  280. RemoteServerError = 502,
  281. /// <summary>
  282. /// Service unavailable
  283. /// </summary>
  284. ServiceUnavailable = 503,
  285. /// <summary>
  286. /// Remote server timeout
  287. /// </summary>
  288. RemoteServerTimeout = 504,
  289. /// <summary>
  290. /// Disconnected
  291. /// </summary>
  292. Disconnected = 510
  293. }
  294. /// <summary>
  295. /// Summary description for Error.
  296. /// </summary>
  297. public class Error : Element
  298. {
  299. #region << Constructors >>
  300. public Error()
  301. {
  302. this.Namespace = Uri.CLIENT;
  303. this.TagName = "error";
  304. }
  305. #region << Obsolete Constructors >>
  306. [Obsolete("Please don't use old Jabber style errors. Use XMPP ErrorCondition instead")]
  307. public Error(int code) : this()
  308. {
  309. this.SetAttribute("code", code.ToString());
  310. }
  311. [Obsolete("Please don't use old Jabber style errors. Use XMPP ErrorCondition instead")]
  312. public Error(ErrorCode code) : this()
  313. {
  314. this.SetAttribute("code", (int)code);
  315. }
  316. #endregion
  317. /// <summary>
  318. /// Creates an error Element according the the condition
  319. /// The type attrib as added automatically as decribed in the XMPP specs
  320. /// This is the prefered way to create error Elements
  321. /// </summary>
  322. /// <param name="condition"></param>
  323. public Error(ErrorCondition condition) : this()
  324. {
  325. this.Condition = condition;
  326. }
  327. public Error(ErrorCondition condition, string text) : this(condition)
  328. {
  329. ErrorText = text;
  330. }
  331. public Error(ErrorType type)
  332. : this()
  333. {
  334. Type = type;
  335. }
  336. public Error(ErrorType type, ErrorCondition condition) : this(type)
  337. {
  338. this.Condition = condition;
  339. }
  340. #endregion
  341. /// <summary>
  342. /// The error Description
  343. /// </summary>
  344. [Obsolete("Use ErrorText Property instead")]
  345. public string Message
  346. {
  347. get
  348. {
  349. return this.Value;
  350. }
  351. set
  352. {
  353. this.Value = value;
  354. }
  355. }
  356. /// <summary>
  357. /// The optional error text
  358. /// </summary>
  359. public string ErrorText
  360. {
  361. get
  362. {
  363. return GetTag("text");
  364. }
  365. set
  366. {
  367. SetTag("text", value, Uri.STANZAS);
  368. }
  369. }
  370. public ErrorCode Code
  371. {
  372. get
  373. {
  374. return (ErrorCode) GetAttributeInt("code");
  375. }
  376. set
  377. {
  378. SetAttribute("code", (int) value);
  379. }
  380. }
  381. public ErrorType Type
  382. {
  383. get
  384. {
  385. return (ErrorType) GetAttributeEnum("type", typeof(ErrorType));
  386. }
  387. set
  388. {
  389. SetAttribute("type", value.ToString());
  390. }
  391. }
  392. public ErrorCondition Condition
  393. {
  394. get
  395. {
  396. if (HasTag("bad-request")) // <bad-request/>
  397. return ErrorCondition.BadRequest;
  398. else if (HasTag("conflict")) // <conflict/>
  399. return ErrorCondition.Conflict;
  400. else if (HasTag("feature-not-implemented"))// <feature-not-implemented/>
  401. return ErrorCondition.FeatureNotImplemented;
  402. else if (HasTag("forbidden")) // <forbidden/>
  403. return ErrorCondition.Forbidden;
  404. else if (HasTag("gone")) // <gone/>
  405. return ErrorCondition.Gone;
  406. else if (HasTag("internal-server-error")) // <internal-server-error/>
  407. return ErrorCondition.InternalServerError;
  408. else if (HasTag("item-not-found")) // <item-not-found/>
  409. return ErrorCondition.ItemNotFound;
  410. else if (HasTag("jid-malformed")) // <jid-malformed/>
  411. return ErrorCondition.JidMalformed;
  412. else if (HasTag("not-acceptable")) // <not-acceptable/>
  413. return ErrorCondition.NotAcceptable;
  414. else if (HasTag("not-allowed")) // <not-allowed/>
  415. return ErrorCondition.NotAllowed;
  416. else if (HasTag("not-authorized")) // <not-authorized/>
  417. return ErrorCondition.NotAuthorized;
  418. else if (HasTag("not-modified")) // <not-modified/>
  419. return ErrorCondition.NotModified;
  420. else if (HasTag("payment-required")) // <payment-required/>
  421. return ErrorCondition.PaymentRequired;
  422. else if (HasTag("recipient-unavailable")) // <recipient-unavailable/>
  423. return ErrorCondition.RecipientUnavailable;
  424. else if (HasTag("redirect")) // <redirect/>
  425. return ErrorCondition.Redirect;
  426. else if (HasTag("registration-required")) // <registration-required/>
  427. return ErrorCondition.RegistrationRequired;
  428. else if (HasTag("remote-server-not-found")) // <remote-server-not-found/>
  429. return ErrorCondition.RemoteServerNotFound;
  430. else if (HasTag("remote-server-timeout")) // <remote-server-timeout/>
  431. return ErrorCondition.RemoteServerTimeout;
  432. else if (HasTag("resource-constraint")) // <resource-constraint/>
  433. return ErrorCondition.ResourceConstraint;
  434. else if (HasTag("service-unavailable")) // <service-unavailable/>
  435. return ErrorCondition.ServiceUnavailable;
  436. else if (HasTag("subscription-required")) // <subscription-required/>
  437. return ErrorCondition.SubscriptionRequired;
  438. else if (HasTag("undefined-condition")) // <undefined-condition/>
  439. return ErrorCondition.UndefinedCondition;
  440. else if (HasTag("unexpected-request")) // <unexpected-request/>
  441. return ErrorCondition.UnexpectedRequest;
  442. else
  443. return ErrorCondition.UndefinedCondition;
  444. }
  445. set
  446. {
  447. switch (value)
  448. {
  449. case ErrorCondition.BadRequest:
  450. SetTag("bad-request", "", Uri.STANZAS);
  451. Type = ErrorType.modify;
  452. break;
  453. case ErrorCondition.Conflict:
  454. SetTag("conflict", "", Uri.STANZAS);
  455. Type = ErrorType.cancel;
  456. break;
  457. case ErrorCondition.FeatureNotImplemented:
  458. SetTag("feature-not-implemented", "", Uri.STANZAS);
  459. Type = ErrorType.cancel;
  460. break;
  461. case ErrorCondition.Forbidden:
  462. SetTag("forbidden", "", Uri.STANZAS);
  463. Type = ErrorType.auth;
  464. break;
  465. case ErrorCondition.Gone:
  466. SetTag("gone", "", Uri.STANZAS);
  467. Type = ErrorType.modify;
  468. break;
  469. case ErrorCondition.InternalServerError:
  470. SetTag("internal-server-error", "", Uri.STANZAS);
  471. Type = ErrorType.wait;
  472. break;
  473. case ErrorCondition.ItemNotFound:
  474. SetTag("item-not-found", "", Uri.STANZAS);
  475. Type = ErrorType.cancel;
  476. break;
  477. case ErrorCondition.JidMalformed:
  478. SetTag("jid-malformed", "", Uri.STANZAS);
  479. Type = ErrorType.modify;
  480. break;
  481. case ErrorCondition.NotAcceptable:
  482. SetTag("not-acceptable", "", Uri.STANZAS);
  483. Type = ErrorType.modify;
  484. break;
  485. case ErrorCondition.NotAllowed:
  486. SetTag("not-allowed", "", Uri.STANZAS);
  487. Type = ErrorType.cancel;
  488. break;
  489. case ErrorCondition.NotAuthorized:
  490. SetTag("not-authorized", "", Uri.STANZAS);
  491. Type = ErrorType.auth;
  492. break;
  493. case ErrorCondition.NotModified:
  494. SetTag("not-modified", "", Uri.STANZAS);
  495. Type = ErrorType.modify;
  496. break;
  497. case ErrorCondition.PaymentRequired:
  498. SetTag("payment-required", "", Uri.STANZAS);
  499. Type = ErrorType.auth;
  500. break;
  501. case ErrorCondition.RecipientUnavailable:
  502. SetTag("recipient-unavailable", "", Uri.STANZAS);
  503. Type = ErrorType.wait;
  504. break;
  505. case ErrorCondition.Redirect:
  506. SetTag("redirect", "", Uri.STANZAS);
  507. Type = ErrorType.modify;
  508. break;
  509. case ErrorCondition.RegistrationRequired:
  510. SetTag("registration-required", "", Uri.STANZAS);
  511. Type = ErrorType.auth;
  512. break;
  513. case ErrorCondition.RemoteServerNotFound:
  514. SetTag("remote-server-not-found", "", Uri.STANZAS);
  515. Type = ErrorType.cancel;
  516. break;
  517. case ErrorCondition.RemoteServerTimeout:
  518. SetTag("remote-server-timeout", "", Uri.STANZAS);
  519. Type = ErrorType.wait;
  520. break;
  521. case ErrorCondition.ResourceConstraint:
  522. SetTag("resource-constraint", "", Uri.STANZAS);
  523. Type = ErrorType.wait;
  524. break;
  525. case ErrorCondition.ServiceUnavailable:
  526. SetTag("service-unavailable", "", Uri.STANZAS);
  527. Type = ErrorType.cancel;
  528. break;
  529. case ErrorCondition.SubscriptionRequired:
  530. SetTag("subscription-required", "", Uri.STANZAS);
  531. Type = ErrorType.auth;
  532. break;
  533. case ErrorCondition.UndefinedCondition:
  534. SetTag("undefined-condition", "", Uri.STANZAS);
  535. // could be any
  536. break;
  537. case ErrorCondition.UnexpectedRequest:
  538. SetTag("unexpected-request", "", Uri.STANZAS);
  539. Type = ErrorType.wait;
  540. break;
  541. }
  542. }
  543. }
  544. }
  545. }