WebHeaderCollection.cs 52 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889
  1. #region License
  2. /*
  3. * WebHeaderCollection.cs
  4. *
  5. * This code is derived from WebHeaderCollection.cs (System.Net) of Mono
  6. * (http://www.mono-project.com).
  7. *
  8. * The MIT License
  9. *
  10. * Copyright (c) 2003 Ximian, Inc. (http://www.ximian.com)
  11. * Copyright (c) 2007 Novell, Inc. (http://www.novell.com)
  12. * Copyright (c) 2012-2020 sta.blockhead
  13. *
  14. * Permission is hereby granted, free of charge, to any person obtaining a copy
  15. * of this software and associated documentation files (the "Software"), to deal
  16. * in the Software without restriction, including without limitation the rights
  17. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  18. * copies of the Software, and to permit persons to whom the Software is
  19. * furnished to do so, subject to the following conditions:
  20. *
  21. * The above copyright notice and this permission notice shall be included in
  22. * all copies or substantial portions of the Software.
  23. *
  24. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  25. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  26. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  27. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  28. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  29. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  30. * THE SOFTWARE.
  31. */
  32. #endregion
  33. #region Authors
  34. /*
  35. * Authors:
  36. * - Lawrence Pit <loz@cable.a2000.nl>
  37. * - Gonzalo Paniagua Javier <gonzalo@ximian.com>
  38. * - Miguel de Icaza <miguel@novell.com>
  39. */
  40. #endregion
  41. using System;
  42. using System.Collections;
  43. using System.Collections.Generic;
  44. using System.Collections.Specialized;
  45. using System.Runtime.InteropServices;
  46. using System.Runtime.Serialization;
  47. using System.Security.Permissions;
  48. using System.Text;
  49. namespace WebSocketSharp.Net
  50. {
  51. /// <summary>
  52. /// Provides a collection of the HTTP headers associated with a request or
  53. /// response.
  54. /// </summary>
  55. [Serializable]
  56. [ComVisible (true)]
  57. public class WebHeaderCollection : NameValueCollection, ISerializable
  58. {
  59. #region Private Fields
  60. private static readonly Dictionary<string, HttpHeaderInfo> _headers;
  61. private bool _internallyUsed;
  62. private HttpHeaderType _state;
  63. #endregion
  64. #region Static Constructor
  65. static WebHeaderCollection ()
  66. {
  67. _headers =
  68. new Dictionary<string, HttpHeaderInfo> (
  69. StringComparer.InvariantCultureIgnoreCase
  70. )
  71. {
  72. {
  73. "Accept",
  74. new HttpHeaderInfo (
  75. "Accept",
  76. HttpHeaderType.Request
  77. | HttpHeaderType.Restricted
  78. | HttpHeaderType.MultiValue
  79. )
  80. },
  81. {
  82. "AcceptCharset",
  83. new HttpHeaderInfo (
  84. "Accept-Charset",
  85. HttpHeaderType.Request | HttpHeaderType.MultiValue
  86. )
  87. },
  88. {
  89. "AcceptEncoding",
  90. new HttpHeaderInfo (
  91. "Accept-Encoding",
  92. HttpHeaderType.Request | HttpHeaderType.MultiValue
  93. )
  94. },
  95. {
  96. "AcceptLanguage",
  97. new HttpHeaderInfo (
  98. "Accept-Language",
  99. HttpHeaderType.Request | HttpHeaderType.MultiValue
  100. )
  101. },
  102. {
  103. "AcceptRanges",
  104. new HttpHeaderInfo (
  105. "Accept-Ranges",
  106. HttpHeaderType.Response | HttpHeaderType.MultiValue
  107. )
  108. },
  109. {
  110. "Age",
  111. new HttpHeaderInfo (
  112. "Age",
  113. HttpHeaderType.Response
  114. )
  115. },
  116. {
  117. "Allow",
  118. new HttpHeaderInfo (
  119. "Allow",
  120. HttpHeaderType.Request
  121. | HttpHeaderType.Response
  122. | HttpHeaderType.MultiValue
  123. )
  124. },
  125. {
  126. "Authorization",
  127. new HttpHeaderInfo (
  128. "Authorization",
  129. HttpHeaderType.Request | HttpHeaderType.MultiValue
  130. )
  131. },
  132. {
  133. "CacheControl",
  134. new HttpHeaderInfo (
  135. "Cache-Control",
  136. HttpHeaderType.Request
  137. | HttpHeaderType.Response
  138. | HttpHeaderType.MultiValue
  139. )
  140. },
  141. {
  142. "Connection",
  143. new HttpHeaderInfo (
  144. "Connection",
  145. HttpHeaderType.Request
  146. | HttpHeaderType.Response
  147. | HttpHeaderType.Restricted
  148. | HttpHeaderType.MultiValue
  149. )
  150. },
  151. {
  152. "ContentEncoding",
  153. new HttpHeaderInfo (
  154. "Content-Encoding",
  155. HttpHeaderType.Request
  156. | HttpHeaderType.Response
  157. | HttpHeaderType.MultiValue
  158. )
  159. },
  160. {
  161. "ContentLanguage",
  162. new HttpHeaderInfo (
  163. "Content-Language",
  164. HttpHeaderType.Request
  165. | HttpHeaderType.Response
  166. | HttpHeaderType.MultiValue
  167. )
  168. },
  169. {
  170. "ContentLength",
  171. new HttpHeaderInfo (
  172. "Content-Length",
  173. HttpHeaderType.Request
  174. | HttpHeaderType.Response
  175. | HttpHeaderType.Restricted
  176. )
  177. },
  178. {
  179. "ContentLocation",
  180. new HttpHeaderInfo (
  181. "Content-Location",
  182. HttpHeaderType.Request | HttpHeaderType.Response
  183. )
  184. },
  185. {
  186. "ContentMd5",
  187. new HttpHeaderInfo (
  188. "Content-MD5",
  189. HttpHeaderType.Request | HttpHeaderType.Response
  190. )
  191. },
  192. {
  193. "ContentRange",
  194. new HttpHeaderInfo (
  195. "Content-Range",
  196. HttpHeaderType.Request | HttpHeaderType.Response
  197. )
  198. },
  199. {
  200. "ContentType",
  201. new HttpHeaderInfo (
  202. "Content-Type",
  203. HttpHeaderType.Request
  204. | HttpHeaderType.Response
  205. | HttpHeaderType.Restricted
  206. )
  207. },
  208. {
  209. "Cookie",
  210. new HttpHeaderInfo (
  211. "Cookie",
  212. HttpHeaderType.Request
  213. )
  214. },
  215. {
  216. "Cookie2",
  217. new HttpHeaderInfo (
  218. "Cookie2",
  219. HttpHeaderType.Request
  220. )
  221. },
  222. {
  223. "Date",
  224. new HttpHeaderInfo (
  225. "Date",
  226. HttpHeaderType.Request
  227. | HttpHeaderType.Response
  228. | HttpHeaderType.Restricted
  229. )
  230. },
  231. {
  232. "Expect",
  233. new HttpHeaderInfo (
  234. "Expect",
  235. HttpHeaderType.Request
  236. | HttpHeaderType.Restricted
  237. | HttpHeaderType.MultiValue
  238. )
  239. },
  240. {
  241. "Expires",
  242. new HttpHeaderInfo (
  243. "Expires",
  244. HttpHeaderType.Request | HttpHeaderType.Response
  245. )
  246. },
  247. {
  248. "ETag",
  249. new HttpHeaderInfo (
  250. "ETag",
  251. HttpHeaderType.Response
  252. )
  253. },
  254. {
  255. "From",
  256. new HttpHeaderInfo (
  257. "From",
  258. HttpHeaderType.Request
  259. )
  260. },
  261. {
  262. "Host",
  263. new HttpHeaderInfo (
  264. "Host",
  265. HttpHeaderType.Request | HttpHeaderType.Restricted
  266. )
  267. },
  268. {
  269. "IfMatch",
  270. new HttpHeaderInfo (
  271. "If-Match",
  272. HttpHeaderType.Request | HttpHeaderType.MultiValue
  273. )
  274. },
  275. {
  276. "IfModifiedSince",
  277. new HttpHeaderInfo (
  278. "If-Modified-Since",
  279. HttpHeaderType.Request | HttpHeaderType.Restricted
  280. )
  281. },
  282. {
  283. "IfNoneMatch",
  284. new HttpHeaderInfo (
  285. "If-None-Match",
  286. HttpHeaderType.Request | HttpHeaderType.MultiValue
  287. )
  288. },
  289. {
  290. "IfRange",
  291. new HttpHeaderInfo (
  292. "If-Range",
  293. HttpHeaderType.Request
  294. )
  295. },
  296. {
  297. "IfUnmodifiedSince",
  298. new HttpHeaderInfo (
  299. "If-Unmodified-Since",
  300. HttpHeaderType.Request
  301. )
  302. },
  303. {
  304. "KeepAlive",
  305. new HttpHeaderInfo (
  306. "Keep-Alive",
  307. HttpHeaderType.Request
  308. | HttpHeaderType.Response
  309. | HttpHeaderType.MultiValue
  310. )
  311. },
  312. {
  313. "LastModified",
  314. new HttpHeaderInfo (
  315. "Last-Modified",
  316. HttpHeaderType.Request | HttpHeaderType.Response
  317. )
  318. },
  319. {
  320. "Location",
  321. new HttpHeaderInfo (
  322. "Location",
  323. HttpHeaderType.Response
  324. )
  325. },
  326. {
  327. "MaxForwards",
  328. new HttpHeaderInfo (
  329. "Max-Forwards",
  330. HttpHeaderType.Request
  331. )
  332. },
  333. {
  334. "Pragma",
  335. new HttpHeaderInfo (
  336. "Pragma",
  337. HttpHeaderType.Request | HttpHeaderType.Response
  338. )
  339. },
  340. {
  341. "ProxyAuthenticate",
  342. new HttpHeaderInfo (
  343. "Proxy-Authenticate",
  344. HttpHeaderType.Response | HttpHeaderType.MultiValue
  345. )
  346. },
  347. {
  348. "ProxyAuthorization",
  349. new HttpHeaderInfo (
  350. "Proxy-Authorization",
  351. HttpHeaderType.Request
  352. )
  353. },
  354. {
  355. "ProxyConnection",
  356. new HttpHeaderInfo (
  357. "Proxy-Connection",
  358. HttpHeaderType.Request
  359. | HttpHeaderType.Response
  360. | HttpHeaderType.Restricted
  361. )
  362. },
  363. {
  364. "Public",
  365. new HttpHeaderInfo (
  366. "Public",
  367. HttpHeaderType.Response | HttpHeaderType.MultiValue
  368. )
  369. },
  370. {
  371. "Range",
  372. new HttpHeaderInfo (
  373. "Range",
  374. HttpHeaderType.Request
  375. | HttpHeaderType.Restricted
  376. | HttpHeaderType.MultiValue
  377. )
  378. },
  379. {
  380. "Referer",
  381. new HttpHeaderInfo (
  382. "Referer",
  383. HttpHeaderType.Request | HttpHeaderType.Restricted
  384. )
  385. },
  386. {
  387. "RetryAfter",
  388. new HttpHeaderInfo (
  389. "Retry-After",
  390. HttpHeaderType.Response
  391. )
  392. },
  393. {
  394. "SecWebSocketAccept",
  395. new HttpHeaderInfo (
  396. "Sec-WebSocket-Accept",
  397. HttpHeaderType.Response | HttpHeaderType.Restricted
  398. )
  399. },
  400. {
  401. "SecWebSocketExtensions",
  402. new HttpHeaderInfo (
  403. "Sec-WebSocket-Extensions",
  404. HttpHeaderType.Request
  405. | HttpHeaderType.Response
  406. | HttpHeaderType.Restricted
  407. | HttpHeaderType.MultiValueInRequest
  408. )
  409. },
  410. {
  411. "SecWebSocketKey",
  412. new HttpHeaderInfo (
  413. "Sec-WebSocket-Key",
  414. HttpHeaderType.Request | HttpHeaderType.Restricted
  415. )
  416. },
  417. {
  418. "SecWebSocketProtocol",
  419. new HttpHeaderInfo (
  420. "Sec-WebSocket-Protocol",
  421. HttpHeaderType.Request
  422. | HttpHeaderType.Response
  423. | HttpHeaderType.MultiValueInRequest
  424. )
  425. },
  426. {
  427. "SecWebSocketVersion",
  428. new HttpHeaderInfo (
  429. "Sec-WebSocket-Version",
  430. HttpHeaderType.Request
  431. | HttpHeaderType.Response
  432. | HttpHeaderType.Restricted
  433. | HttpHeaderType.MultiValueInResponse
  434. )
  435. },
  436. {
  437. "Server",
  438. new HttpHeaderInfo (
  439. "Server",
  440. HttpHeaderType.Response
  441. )
  442. },
  443. {
  444. "SetCookie",
  445. new HttpHeaderInfo (
  446. "Set-Cookie",
  447. HttpHeaderType.Response | HttpHeaderType.MultiValue
  448. )
  449. },
  450. {
  451. "SetCookie2",
  452. new HttpHeaderInfo (
  453. "Set-Cookie2",
  454. HttpHeaderType.Response | HttpHeaderType.MultiValue
  455. )
  456. },
  457. {
  458. "Te",
  459. new HttpHeaderInfo (
  460. "TE",
  461. HttpHeaderType.Request
  462. )
  463. },
  464. {
  465. "Trailer",
  466. new HttpHeaderInfo (
  467. "Trailer",
  468. HttpHeaderType.Request | HttpHeaderType.Response
  469. )
  470. },
  471. {
  472. "TransferEncoding",
  473. new HttpHeaderInfo (
  474. "Transfer-Encoding",
  475. HttpHeaderType.Request
  476. | HttpHeaderType.Response
  477. | HttpHeaderType.Restricted
  478. | HttpHeaderType.MultiValue
  479. )
  480. },
  481. {
  482. "Translate",
  483. new HttpHeaderInfo (
  484. "Translate",
  485. HttpHeaderType.Request
  486. )
  487. },
  488. {
  489. "Upgrade",
  490. new HttpHeaderInfo (
  491. "Upgrade",
  492. HttpHeaderType.Request
  493. | HttpHeaderType.Response
  494. | HttpHeaderType.MultiValue
  495. )
  496. },
  497. {
  498. "UserAgent",
  499. new HttpHeaderInfo (
  500. "User-Agent",
  501. HttpHeaderType.Request | HttpHeaderType.Restricted
  502. )
  503. },
  504. {
  505. "Vary",
  506. new HttpHeaderInfo (
  507. "Vary",
  508. HttpHeaderType.Response | HttpHeaderType.MultiValue
  509. )
  510. },
  511. {
  512. "Via",
  513. new HttpHeaderInfo (
  514. "Via",
  515. HttpHeaderType.Request
  516. | HttpHeaderType.Response
  517. | HttpHeaderType.MultiValue
  518. )
  519. },
  520. {
  521. "Warning",
  522. new HttpHeaderInfo (
  523. "Warning",
  524. HttpHeaderType.Request
  525. | HttpHeaderType.Response
  526. | HttpHeaderType.MultiValue
  527. )
  528. },
  529. {
  530. "WwwAuthenticate",
  531. new HttpHeaderInfo (
  532. "WWW-Authenticate",
  533. HttpHeaderType.Response
  534. | HttpHeaderType.Restricted
  535. | HttpHeaderType.MultiValue
  536. )
  537. }
  538. };
  539. }
  540. #endregion
  541. #region Internal Constructors
  542. internal WebHeaderCollection (HttpHeaderType state, bool internallyUsed)
  543. {
  544. _state = state;
  545. _internallyUsed = internallyUsed;
  546. }
  547. #endregion
  548. #region Protected Constructors
  549. /// <summary>
  550. /// Initializes a new instance of the <see cref="WebHeaderCollection"/> class
  551. /// from the specified instances of the <see cref="SerializationInfo"/> and
  552. /// <see cref="StreamingContext"/> classes.
  553. /// </summary>
  554. /// <param name="serializationInfo">
  555. /// A <see cref="SerializationInfo"/> that contains the serialized
  556. /// object data.
  557. /// </param>
  558. /// <param name="streamingContext">
  559. /// A <see cref="StreamingContext"/> that specifies the source for
  560. /// the deserialization.
  561. /// </param>
  562. /// <exception cref="ArgumentNullException">
  563. /// <paramref name="serializationInfo"/> is <see langword="null"/>.
  564. /// </exception>
  565. /// <exception cref="ArgumentException">
  566. /// An element with the specified name is not found in
  567. /// <paramref name="serializationInfo"/>.
  568. /// </exception>
  569. protected WebHeaderCollection (
  570. SerializationInfo serializationInfo, StreamingContext streamingContext
  571. )
  572. {
  573. if (serializationInfo == null)
  574. throw new ArgumentNullException ("serializationInfo");
  575. try {
  576. _internallyUsed = serializationInfo.GetBoolean ("InternallyUsed");
  577. _state = (HttpHeaderType) serializationInfo.GetInt32 ("State");
  578. var cnt = serializationInfo.GetInt32 ("Count");
  579. for (var i = 0; i < cnt; i++) {
  580. base.Add (
  581. serializationInfo.GetString (i.ToString ()),
  582. serializationInfo.GetString ((cnt + i).ToString ())
  583. );
  584. }
  585. }
  586. catch (SerializationException ex) {
  587. throw new ArgumentException (ex.Message, "serializationInfo", ex);
  588. }
  589. }
  590. #endregion
  591. #region Public Constructors
  592. /// <summary>
  593. /// Initializes a new instance of the <see cref="WebHeaderCollection"/>
  594. /// class.
  595. /// </summary>
  596. public WebHeaderCollection ()
  597. {
  598. }
  599. #endregion
  600. #region Internal Properties
  601. internal HttpHeaderType State {
  602. get {
  603. return _state;
  604. }
  605. }
  606. #endregion
  607. #region Public Properties
  608. /// <summary>
  609. /// Gets all header names in the collection.
  610. /// </summary>
  611. /// <value>
  612. /// An array of <see cref="string"/> that contains all header names in
  613. /// the collection.
  614. /// </value>
  615. public override string[] AllKeys {
  616. get {
  617. return base.AllKeys;
  618. }
  619. }
  620. /// <summary>
  621. /// Gets the number of headers in the collection.
  622. /// </summary>
  623. /// <value>
  624. /// An <see cref="int"/> that represents the number of headers in
  625. /// the collection.
  626. /// </value>
  627. public override int Count {
  628. get {
  629. return base.Count;
  630. }
  631. }
  632. /// <summary>
  633. /// Gets or sets the specified request header.
  634. /// </summary>
  635. /// <value>
  636. /// A <see cref="string"/> that represents the value of the request header.
  637. /// </value>
  638. /// <param name="header">
  639. /// <para>
  640. /// One of the <see cref="HttpRequestHeader"/> enum values.
  641. /// </para>
  642. /// <para>
  643. /// It specifies the request header to get or set.
  644. /// </para>
  645. /// </param>
  646. /// <exception cref="ArgumentException">
  647. /// <para>
  648. /// <paramref name="header"/> is a restricted header.
  649. /// </para>
  650. /// <para>
  651. /// -or-
  652. /// </para>
  653. /// <para>
  654. /// <paramref name="value"/> contains an invalid character.
  655. /// </para>
  656. /// </exception>
  657. /// <exception cref="ArgumentOutOfRangeException">
  658. /// The length of <paramref name="value"/> is greater than 65,535
  659. /// characters.
  660. /// </exception>
  661. /// <exception cref="InvalidOperationException">
  662. /// This instance does not allow the request header.
  663. /// </exception>
  664. public string this[HttpRequestHeader header] {
  665. get {
  666. var key = header.ToString ();
  667. var name = getHeaderName (key);
  668. return Get (name);
  669. }
  670. set {
  671. Add (header, value);
  672. }
  673. }
  674. /// <summary>
  675. /// Gets or sets the specified response header.
  676. /// </summary>
  677. /// <value>
  678. /// A <see cref="string"/> that represents the value of the response header.
  679. /// </value>
  680. /// <param name="header">
  681. /// <para>
  682. /// One of the <see cref="HttpResponseHeader"/> enum values.
  683. /// </para>
  684. /// <para>
  685. /// It specifies the response header to get or set.
  686. /// </para>
  687. /// </param>
  688. /// <exception cref="ArgumentException">
  689. /// <para>
  690. /// <paramref name="header"/> is a restricted header.
  691. /// </para>
  692. /// <para>
  693. /// -or-
  694. /// </para>
  695. /// <para>
  696. /// <paramref name="value"/> contains an invalid character.
  697. /// </para>
  698. /// </exception>
  699. /// <exception cref="ArgumentOutOfRangeException">
  700. /// The length of <paramref name="value"/> is greater than 65,535
  701. /// characters.
  702. /// </exception>
  703. /// <exception cref="InvalidOperationException">
  704. /// This instance does not allow the response header.
  705. /// </exception>
  706. public string this[HttpResponseHeader header] {
  707. get {
  708. var key = header.ToString ();
  709. var name = getHeaderName (key);
  710. return Get (name);
  711. }
  712. set {
  713. Add (header, value);
  714. }
  715. }
  716. /// <summary>
  717. /// Gets a collection of header names in the collection.
  718. /// </summary>
  719. /// <value>
  720. /// A <see cref="NameObjectCollectionBase.KeysCollection"/> that contains
  721. /// all header names in the collection.
  722. /// </value>
  723. public override NameObjectCollectionBase.KeysCollection Keys {
  724. get {
  725. return base.Keys;
  726. }
  727. }
  728. #endregion
  729. #region Private Methods
  730. private void add (string name, string value, HttpHeaderType headerType)
  731. {
  732. base.Add (name, value);
  733. if (_state != HttpHeaderType.Unspecified)
  734. return;
  735. if (headerType == HttpHeaderType.Unspecified)
  736. return;
  737. _state = headerType;
  738. }
  739. private void checkAllowed (HttpHeaderType headerType)
  740. {
  741. if (_state == HttpHeaderType.Unspecified)
  742. return;
  743. if (headerType == HttpHeaderType.Unspecified)
  744. return;
  745. if (headerType != _state) {
  746. var msg = "This instance does not allow the header.";
  747. throw new InvalidOperationException (msg);
  748. }
  749. }
  750. private static string checkName (string name, string paramName)
  751. {
  752. if (name == null) {
  753. var msg = "The name is null.";
  754. throw new ArgumentNullException (paramName, msg);
  755. }
  756. if (name.Length == 0) {
  757. var msg = "The name is an empty string.";
  758. throw new ArgumentException (msg, paramName);
  759. }
  760. name = name.Trim ();
  761. if (name.Length == 0) {
  762. var msg = "The name is a string of spaces.";
  763. throw new ArgumentException (msg, paramName);
  764. }
  765. if (!name.IsToken ()) {
  766. var msg = "The name contains an invalid character.";
  767. throw new ArgumentException (msg, paramName);
  768. }
  769. return name;
  770. }
  771. private void checkRestricted (string name, HttpHeaderType headerType)
  772. {
  773. if (_internallyUsed)
  774. return;
  775. var res = headerType == HttpHeaderType.Response;
  776. if (isRestricted (name, res)) {
  777. var msg = "The header is a restricted header.";
  778. throw new ArgumentException (msg);
  779. }
  780. }
  781. private static string checkValue (string value, string paramName)
  782. {
  783. if (value == null)
  784. return String.Empty;
  785. value = value.Trim ();
  786. var len = value.Length;
  787. if (len == 0)
  788. return value;
  789. if (len > 65535) {
  790. var msg = "The length of the value is greater than 65,535 characters.";
  791. throw new ArgumentOutOfRangeException (paramName, msg);
  792. }
  793. if (!value.IsText ()) {
  794. var msg = "The value contains an invalid character.";
  795. throw new ArgumentException (msg, paramName);
  796. }
  797. return value;
  798. }
  799. private static HttpHeaderInfo getHeaderInfo (string name)
  800. {
  801. var comparison = StringComparison.InvariantCultureIgnoreCase;
  802. foreach (var headerInfo in _headers.Values) {
  803. if (headerInfo.HeaderName.Equals (name, comparison))
  804. return headerInfo;
  805. }
  806. return null;
  807. }
  808. private static string getHeaderName (string key)
  809. {
  810. HttpHeaderInfo headerInfo;
  811. return _headers.TryGetValue (key, out headerInfo)
  812. ? headerInfo.HeaderName
  813. : null;
  814. }
  815. private static HttpHeaderType getHeaderType (string name)
  816. {
  817. var headerInfo = getHeaderInfo (name);
  818. if (headerInfo == null)
  819. return HttpHeaderType.Unspecified;
  820. if (headerInfo.IsRequest) {
  821. return !headerInfo.IsResponse
  822. ? HttpHeaderType.Request
  823. : HttpHeaderType.Unspecified;
  824. }
  825. return headerInfo.IsResponse
  826. ? HttpHeaderType.Response
  827. : HttpHeaderType.Unspecified;
  828. }
  829. private static bool isMultiValue (string name, bool response)
  830. {
  831. var headerInfo = getHeaderInfo (name);
  832. return headerInfo != null && headerInfo.IsMultiValue (response);
  833. }
  834. private static bool isRestricted (string name, bool response)
  835. {
  836. var headerInfo = getHeaderInfo (name);
  837. return headerInfo != null && headerInfo.IsRestricted (response);
  838. }
  839. private void set (string name, string value, HttpHeaderType headerType)
  840. {
  841. base.Set (name, value);
  842. if (_state != HttpHeaderType.Unspecified)
  843. return;
  844. if (headerType == HttpHeaderType.Unspecified)
  845. return;
  846. _state = headerType;
  847. }
  848. #endregion
  849. #region Internal Methods
  850. internal void InternalRemove (string name)
  851. {
  852. base.Remove (name);
  853. }
  854. internal void InternalSet (string header, bool response)
  855. {
  856. var idx = header.IndexOf (':');
  857. if (idx == -1) {
  858. var msg = "It does not contain a colon character.";
  859. throw new ArgumentException (msg, "header");
  860. }
  861. var name = header.Substring (0, idx);
  862. var val = idx < header.Length - 1
  863. ? header.Substring (idx + 1)
  864. : String.Empty;
  865. name = checkName (name, "header");
  866. val = checkValue (val, "header");
  867. if (isMultiValue (name, response)) {
  868. base.Add (name, val);
  869. return;
  870. }
  871. base.Set (name, val);
  872. }
  873. internal void InternalSet (string name, string value, bool response)
  874. {
  875. value = checkValue (value, "value");
  876. if (isMultiValue (name, response)) {
  877. base.Add (name, value);
  878. return;
  879. }
  880. base.Set (name, value);
  881. }
  882. internal string ToStringMultiValue (bool response)
  883. {
  884. var cnt = Count;
  885. if (cnt == 0)
  886. return "\r\n";
  887. var buff = new StringBuilder ();
  888. for (var i = 0; i < cnt; i++) {
  889. var name = GetKey (i);
  890. if (isMultiValue (name, response)) {
  891. foreach (var val in GetValues (i))
  892. buff.AppendFormat ("{0}: {1}\r\n", name, val);
  893. continue;
  894. }
  895. buff.AppendFormat ("{0}: {1}\r\n", name, Get (i));
  896. }
  897. buff.Append ("\r\n");
  898. return buff.ToString ();
  899. }
  900. #endregion
  901. #region Protected Methods
  902. /// <summary>
  903. /// Adds a header to the collection without checking if the header is on
  904. /// the restricted header list.
  905. /// </summary>
  906. /// <param name="headerName">
  907. /// A <see cref="string"/> that specifies the name of the header to add.
  908. /// </param>
  909. /// <param name="headerValue">
  910. /// A <see cref="string"/> that specifies the value of the header to add.
  911. /// </param>
  912. /// <exception cref="ArgumentNullException">
  913. /// <paramref name="headerName"/> is <see langword="null"/>.
  914. /// </exception>
  915. /// <exception cref="ArgumentException">
  916. /// <para>
  917. /// <paramref name="headerName"/> is an empty string.
  918. /// </para>
  919. /// <para>
  920. /// -or-
  921. /// </para>
  922. /// <para>
  923. /// <paramref name="headerName"/> is a string of spaces.
  924. /// </para>
  925. /// <para>
  926. /// -or-
  927. /// </para>
  928. /// <para>
  929. /// <paramref name="headerName"/> contains an invalid character.
  930. /// </para>
  931. /// <para>
  932. /// -or-
  933. /// </para>
  934. /// <para>
  935. /// <paramref name="headerValue"/> contains an invalid character.
  936. /// </para>
  937. /// </exception>
  938. /// <exception cref="ArgumentOutOfRangeException">
  939. /// The length of <paramref name="headerValue"/> is greater than 65,535
  940. /// characters.
  941. /// </exception>
  942. /// <exception cref="InvalidOperationException">
  943. /// This instance does not allow the header.
  944. /// </exception>
  945. protected void AddWithoutValidate (string headerName, string headerValue)
  946. {
  947. headerName = checkName (headerName, "headerName");
  948. headerValue = checkValue (headerValue, "headerValue");
  949. var headerType = getHeaderType (headerName);
  950. checkAllowed (headerType);
  951. add (headerName, headerValue, headerType);
  952. }
  953. #endregion
  954. #region Public Methods
  955. /// <summary>
  956. /// Adds the specified header to the collection.
  957. /// </summary>
  958. /// <param name="header">
  959. /// A <see cref="string"/> that specifies the header to add,
  960. /// with the name and value separated by a colon character (':').
  961. /// </param>
  962. /// <exception cref="ArgumentNullException">
  963. /// <paramref name="header"/> is <see langword="null"/>.
  964. /// </exception>
  965. /// <exception cref="ArgumentException">
  966. /// <para>
  967. /// <paramref name="header"/> is an empty string.
  968. /// </para>
  969. /// <para>
  970. /// -or-
  971. /// </para>
  972. /// <para>
  973. /// <paramref name="header"/> does not contain a colon character.
  974. /// </para>
  975. /// <para>
  976. /// -or-
  977. /// </para>
  978. /// <para>
  979. /// The name part of <paramref name="header"/> is an empty string.
  980. /// </para>
  981. /// <para>
  982. /// -or-
  983. /// </para>
  984. /// <para>
  985. /// The name part of <paramref name="header"/> is a string of spaces.
  986. /// </para>
  987. /// <para>
  988. /// -or-
  989. /// </para>
  990. /// <para>
  991. /// The name part of <paramref name="header"/> contains an invalid
  992. /// character.
  993. /// </para>
  994. /// <para>
  995. /// -or-
  996. /// </para>
  997. /// <para>
  998. /// The value part of <paramref name="header"/> contains an invalid
  999. /// character.
  1000. /// </para>
  1001. /// <para>
  1002. /// -or-
  1003. /// </para>
  1004. /// <para>
  1005. /// <paramref name="header"/> is a restricted header.
  1006. /// </para>
  1007. /// </exception>
  1008. /// <exception cref="ArgumentOutOfRangeException">
  1009. /// The length of the value part of <paramref name="header"/> is greater
  1010. /// than 65,535 characters.
  1011. /// </exception>
  1012. /// <exception cref="InvalidOperationException">
  1013. /// This instance does not allow the header.
  1014. /// </exception>
  1015. public void Add (string header)
  1016. {
  1017. if (header == null)
  1018. throw new ArgumentNullException ("header");
  1019. var len = header.Length;
  1020. if (len == 0) {
  1021. var msg = "An empty string.";
  1022. throw new ArgumentException (msg, "header");
  1023. }
  1024. var idx = header.IndexOf (':');
  1025. if (idx == -1) {
  1026. var msg = "It does not contain a colon character.";
  1027. throw new ArgumentException (msg, "header");
  1028. }
  1029. var name = header.Substring (0, idx);
  1030. var val = idx < len - 1
  1031. ? header.Substring (idx + 1)
  1032. : String.Empty;
  1033. name = checkName (name, "header");
  1034. val = checkValue (val, "header");
  1035. var headerType = getHeaderType (name);
  1036. checkRestricted (name, headerType);
  1037. checkAllowed (headerType);
  1038. add (name, val, headerType);
  1039. }
  1040. /// <summary>
  1041. /// Adds the specified request header with the specified value to
  1042. /// the collection.
  1043. /// </summary>
  1044. /// <param name="header">
  1045. /// <para>
  1046. /// One of the <see cref="HttpRequestHeader"/> enum values.
  1047. /// </para>
  1048. /// <para>
  1049. /// It specifies the request header to add.
  1050. /// </para>
  1051. /// </param>
  1052. /// <param name="value">
  1053. /// A <see cref="string"/> that specifies the value of the header to add.
  1054. /// </param>
  1055. /// <exception cref="ArgumentException">
  1056. /// <para>
  1057. /// <paramref name="value"/> contains an invalid character.
  1058. /// </para>
  1059. /// <para>
  1060. /// -or-
  1061. /// </para>
  1062. /// <para>
  1063. /// <paramref name="header"/> is a restricted header.
  1064. /// </para>
  1065. /// </exception>
  1066. /// <exception cref="ArgumentOutOfRangeException">
  1067. /// The length of <paramref name="value"/> is greater than 65,535
  1068. /// characters.
  1069. /// </exception>
  1070. /// <exception cref="InvalidOperationException">
  1071. /// This instance does not allow the request header.
  1072. /// </exception>
  1073. public void Add (HttpRequestHeader header, string value)
  1074. {
  1075. value = checkValue (value, "value");
  1076. var key = header.ToString ();
  1077. var name = getHeaderName (key);
  1078. checkRestricted (name, HttpHeaderType.Request);
  1079. checkAllowed (HttpHeaderType.Request);
  1080. add (name, value, HttpHeaderType.Request);
  1081. }
  1082. /// <summary>
  1083. /// Adds the specified response header with the specified value to
  1084. /// the collection.
  1085. /// </summary>
  1086. /// <param name="header">
  1087. /// <para>
  1088. /// One of the <see cref="HttpResponseHeader"/> enum values.
  1089. /// </para>
  1090. /// <para>
  1091. /// It specifies the response header to add.
  1092. /// </para>
  1093. /// </param>
  1094. /// <param name="value">
  1095. /// A <see cref="string"/> that specifies the value of the header to add.
  1096. /// </param>
  1097. /// <exception cref="ArgumentException">
  1098. /// <para>
  1099. /// <paramref name="value"/> contains an invalid character.
  1100. /// </para>
  1101. /// <para>
  1102. /// -or-
  1103. /// </para>
  1104. /// <para>
  1105. /// <paramref name="header"/> is a restricted header.
  1106. /// </para>
  1107. /// </exception>
  1108. /// <exception cref="ArgumentOutOfRangeException">
  1109. /// The length of <paramref name="value"/> is greater than 65,535
  1110. /// characters.
  1111. /// </exception>
  1112. /// <exception cref="InvalidOperationException">
  1113. /// This instance does not allow the response header.
  1114. /// </exception>
  1115. public void Add (HttpResponseHeader header, string value)
  1116. {
  1117. value = checkValue (value, "value");
  1118. var key = header.ToString ();
  1119. var name = getHeaderName (key);
  1120. checkRestricted (name, HttpHeaderType.Response);
  1121. checkAllowed (HttpHeaderType.Response);
  1122. add (name, value, HttpHeaderType.Response);
  1123. }
  1124. /// <summary>
  1125. /// Adds a header with the specified name and value to the collection.
  1126. /// </summary>
  1127. /// <param name="name">
  1128. /// A <see cref="string"/> that specifies the name of the header to add.
  1129. /// </param>
  1130. /// <param name="value">
  1131. /// A <see cref="string"/> that specifies the value of the header to add.
  1132. /// </param>
  1133. /// <exception cref="ArgumentNullException">
  1134. /// <paramref name="name"/> is <see langword="null"/>.
  1135. /// </exception>
  1136. /// <exception cref="ArgumentException">
  1137. /// <para>
  1138. /// <paramref name="name"/> is an empty string.
  1139. /// </para>
  1140. /// <para>
  1141. /// -or-
  1142. /// </para>
  1143. /// <para>
  1144. /// <paramref name="name"/> is a string of spaces.
  1145. /// </para>
  1146. /// <para>
  1147. /// -or-
  1148. /// </para>
  1149. /// <para>
  1150. /// <paramref name="name"/> contains an invalid character.
  1151. /// </para>
  1152. /// <para>
  1153. /// -or-
  1154. /// </para>
  1155. /// <para>
  1156. /// <paramref name="value"/> contains an invalid character.
  1157. /// </para>
  1158. /// <para>
  1159. /// -or-
  1160. /// </para>
  1161. /// <para>
  1162. /// <paramref name="name"/> is a restricted header name.
  1163. /// </para>
  1164. /// </exception>
  1165. /// <exception cref="ArgumentOutOfRangeException">
  1166. /// The length of <paramref name="value"/> is greater than 65,535
  1167. /// characters.
  1168. /// </exception>
  1169. /// <exception cref="InvalidOperationException">
  1170. /// This instance does not allow the header.
  1171. /// </exception>
  1172. public override void Add (string name, string value)
  1173. {
  1174. name = checkName (name, "name");
  1175. value = checkValue (value, "value");
  1176. var headerType = getHeaderType (name);
  1177. checkRestricted (name, headerType);
  1178. checkAllowed (headerType);
  1179. add (name, value, headerType);
  1180. }
  1181. /// <summary>
  1182. /// Removes all headers from the collection.
  1183. /// </summary>
  1184. public override void Clear ()
  1185. {
  1186. base.Clear ();
  1187. _state = HttpHeaderType.Unspecified;
  1188. }
  1189. /// <summary>
  1190. /// Get the value of the header at the specified index in the collection.
  1191. /// </summary>
  1192. /// <returns>
  1193. /// A <see cref="string"/> that receives the value of the header.
  1194. /// </returns>
  1195. /// <param name="index">
  1196. /// An <see cref="int"/> that specifies the zero-based index of the header
  1197. /// to find.
  1198. /// </param>
  1199. /// <exception cref="ArgumentOutOfRangeException">
  1200. /// <paramref name="index"/> is out of allowable range of indexes for
  1201. /// the collection.
  1202. /// </exception>
  1203. public override string Get (int index)
  1204. {
  1205. return base.Get (index);
  1206. }
  1207. /// <summary>
  1208. /// Get the value of the header with the specified name in the collection.
  1209. /// </summary>
  1210. /// <returns>
  1211. /// <para>
  1212. /// A <see cref="string"/> that receives the value of the header.
  1213. /// </para>
  1214. /// <para>
  1215. /// <see langword="null"/> if not found.
  1216. /// </para>
  1217. /// </returns>
  1218. /// <param name="name">
  1219. /// A <see cref="string"/> that specifies the name of the header to find.
  1220. /// </param>
  1221. public override string Get (string name)
  1222. {
  1223. return base.Get (name);
  1224. }
  1225. /// <summary>
  1226. /// Gets the enumerator used to iterate through the collection.
  1227. /// </summary>
  1228. /// <returns>
  1229. /// An <see cref="IEnumerator"/> instance used to iterate through
  1230. /// the collection.
  1231. /// </returns>
  1232. public override IEnumerator GetEnumerator ()
  1233. {
  1234. return base.GetEnumerator ();
  1235. }
  1236. /// <summary>
  1237. /// Get the name of the header at the specified index in the collection.
  1238. /// </summary>
  1239. /// <returns>
  1240. /// A <see cref="string"/> that receives the name of the header.
  1241. /// </returns>
  1242. /// <param name="index">
  1243. /// An <see cref="int"/> that specifies the zero-based index of the header
  1244. /// to find.
  1245. /// </param>
  1246. /// <exception cref="ArgumentOutOfRangeException">
  1247. /// <paramref name="index"/> is out of allowable range of indexes for
  1248. /// the collection.
  1249. /// </exception>
  1250. public override string GetKey (int index)
  1251. {
  1252. return base.GetKey (index);
  1253. }
  1254. /// <summary>
  1255. /// Get the values of the header at the specified index in the collection.
  1256. /// </summary>
  1257. /// <returns>
  1258. /// <para>
  1259. /// An array of <see cref="string"/> that receives the values of
  1260. /// the header.
  1261. /// </para>
  1262. /// <para>
  1263. /// <see langword="null"/> if not present.
  1264. /// </para>
  1265. /// </returns>
  1266. /// <param name="index">
  1267. /// An <see cref="int"/> that specifies the zero-based index of the header
  1268. /// to find.
  1269. /// </param>
  1270. /// <exception cref="ArgumentOutOfRangeException">
  1271. /// <paramref name="index"/> is out of allowable range of indexes for
  1272. /// the collection.
  1273. /// </exception>
  1274. public override string[] GetValues (int index)
  1275. {
  1276. var vals = base.GetValues (index);
  1277. return vals != null && vals.Length > 0 ? vals : null;
  1278. }
  1279. /// <summary>
  1280. /// Get the values of the header with the specified name in the collection.
  1281. /// </summary>
  1282. /// <returns>
  1283. /// <para>
  1284. /// An array of <see cref="string"/> that receives the values of
  1285. /// the header.
  1286. /// </para>
  1287. /// <para>
  1288. /// <see langword="null"/> if not present.
  1289. /// </para>
  1290. /// </returns>
  1291. /// <param name="name">
  1292. /// A <see cref="string"/> that specifies the name of the header to find.
  1293. /// </param>
  1294. public override string[] GetValues (string name)
  1295. {
  1296. var vals = base.GetValues (name);
  1297. return vals != null && vals.Length > 0 ? vals : null;
  1298. }
  1299. /// <summary>
  1300. /// Populates a <see cref="SerializationInfo"/> instance with the data
  1301. /// needed to serialize this instance.
  1302. /// </summary>
  1303. /// <param name="serializationInfo">
  1304. /// A <see cref="SerializationInfo"/> to populate with the data.
  1305. /// </param>
  1306. /// <param name="streamingContext">
  1307. /// A <see cref="StreamingContext"/> that specifies the destination for
  1308. /// the serialization.
  1309. /// </param>
  1310. /// <exception cref="ArgumentNullException">
  1311. /// <paramref name="serializationInfo"/> is <see langword="null"/>.
  1312. /// </exception>
  1313. [
  1314. SecurityPermission (
  1315. SecurityAction.LinkDemand,
  1316. Flags = SecurityPermissionFlag.SerializationFormatter
  1317. )
  1318. ]
  1319. public override void GetObjectData (
  1320. SerializationInfo serializationInfo, StreamingContext streamingContext
  1321. )
  1322. {
  1323. if (serializationInfo == null)
  1324. throw new ArgumentNullException ("serializationInfo");
  1325. serializationInfo.AddValue ("InternallyUsed", _internallyUsed);
  1326. serializationInfo.AddValue ("State", (int) _state);
  1327. var cnt = Count;
  1328. serializationInfo.AddValue ("Count", cnt);
  1329. for (var i = 0; i < cnt; i++) {
  1330. serializationInfo.AddValue (i.ToString (), GetKey (i));
  1331. serializationInfo.AddValue ((cnt + i).ToString (), Get (i));
  1332. }
  1333. }
  1334. /// <summary>
  1335. /// Determines whether the specified HTTP header can be set for the request.
  1336. /// </summary>
  1337. /// <returns>
  1338. /// <c>true</c> if the header cannot be set; otherwise, <c>false</c>.
  1339. /// </returns>
  1340. /// <param name="headerName">
  1341. /// A <see cref="string"/> that specifies the name of the header to test.
  1342. /// </param>
  1343. /// <exception cref="ArgumentNullException">
  1344. /// <paramref name="headerName"/> is <see langword="null"/>.
  1345. /// </exception>
  1346. /// <exception cref="ArgumentException">
  1347. /// <para>
  1348. /// <paramref name="headerName"/> is an empty string.
  1349. /// </para>
  1350. /// <para>
  1351. /// -or-
  1352. /// </para>
  1353. /// <para>
  1354. /// <paramref name="headerName"/> is a string of spaces.
  1355. /// </para>
  1356. /// <para>
  1357. /// -or-
  1358. /// </para>
  1359. /// <para>
  1360. /// <paramref name="headerName"/> contains an invalid character.
  1361. /// </para>
  1362. /// </exception>
  1363. public static bool IsRestricted (string headerName)
  1364. {
  1365. return IsRestricted (headerName, false);
  1366. }
  1367. /// <summary>
  1368. /// Determines whether the specified HTTP header can be set for the request
  1369. /// or the response.
  1370. /// </summary>
  1371. /// <returns>
  1372. /// <c>true</c> if the header cannot be set; otherwise, <c>false</c>.
  1373. /// </returns>
  1374. /// <param name="headerName">
  1375. /// A <see cref="string"/> that specifies the name of the header to test.
  1376. /// </param>
  1377. /// <param name="response">
  1378. /// A <see cref="bool"/>: <c>true</c> if the test is for the response;
  1379. /// otherwise, <c>false</c>.
  1380. /// </param>
  1381. /// <exception cref="ArgumentNullException">
  1382. /// <paramref name="headerName"/> is <see langword="null"/>.
  1383. /// </exception>
  1384. /// <exception cref="ArgumentException">
  1385. /// <para>
  1386. /// <paramref name="headerName"/> is an empty string.
  1387. /// </para>
  1388. /// <para>
  1389. /// -or-
  1390. /// </para>
  1391. /// <para>
  1392. /// <paramref name="headerName"/> is a string of spaces.
  1393. /// </para>
  1394. /// <para>
  1395. /// -or-
  1396. /// </para>
  1397. /// <para>
  1398. /// <paramref name="headerName"/> contains an invalid character.
  1399. /// </para>
  1400. /// </exception>
  1401. public static bool IsRestricted (string headerName, bool response)
  1402. {
  1403. headerName = checkName (headerName, "headerName");
  1404. return isRestricted (headerName, response);
  1405. }
  1406. /// <summary>
  1407. /// Implements the <see cref="ISerializable"/> interface and raises
  1408. /// the deserialization event when the deserialization is complete.
  1409. /// </summary>
  1410. /// <param name="sender">
  1411. /// An <see cref="object"/> instance that represents the source of
  1412. /// the deserialization event.
  1413. /// </param>
  1414. public override void OnDeserialization (object sender)
  1415. {
  1416. }
  1417. /// <summary>
  1418. /// Removes the specified request header from the collection.
  1419. /// </summary>
  1420. /// <param name="header">
  1421. /// <para>
  1422. /// One of the <see cref="HttpRequestHeader"/> enum values.
  1423. /// </para>
  1424. /// <para>
  1425. /// It specifies the request header to remove.
  1426. /// </para>
  1427. /// </param>
  1428. /// <exception cref="ArgumentException">
  1429. /// <paramref name="header"/> is a restricted header.
  1430. /// </exception>
  1431. /// <exception cref="InvalidOperationException">
  1432. /// This instance does not allow the request header.
  1433. /// </exception>
  1434. public void Remove (HttpRequestHeader header)
  1435. {
  1436. var key = header.ToString ();
  1437. var name = getHeaderName (key);
  1438. checkRestricted (name, HttpHeaderType.Request);
  1439. checkAllowed (HttpHeaderType.Request);
  1440. base.Remove (name);
  1441. }
  1442. /// <summary>
  1443. /// Removes the specified response header from the collection.
  1444. /// </summary>
  1445. /// <param name="header">
  1446. /// <para>
  1447. /// One of the <see cref="HttpResponseHeader"/> enum values.
  1448. /// </para>
  1449. /// <para>
  1450. /// It specifies the response header to remove.
  1451. /// </para>
  1452. /// </param>
  1453. /// <exception cref="ArgumentException">
  1454. /// <paramref name="header"/> is a restricted header.
  1455. /// </exception>
  1456. /// <exception cref="InvalidOperationException">
  1457. /// This instance does not allow the response header.
  1458. /// </exception>
  1459. public void Remove (HttpResponseHeader header)
  1460. {
  1461. var key = header.ToString ();
  1462. var name = getHeaderName (key);
  1463. checkRestricted (name, HttpHeaderType.Response);
  1464. checkAllowed (HttpHeaderType.Response);
  1465. base.Remove (name);
  1466. }
  1467. /// <summary>
  1468. /// Removes the specified header from the collection.
  1469. /// </summary>
  1470. /// <param name="name">
  1471. /// A <see cref="string"/> that specifies the name of the header to remove.
  1472. /// </param>
  1473. /// <exception cref="ArgumentNullException">
  1474. /// <paramref name="name"/> is <see langword="null"/>.
  1475. /// </exception>
  1476. /// <exception cref="ArgumentException">
  1477. /// <para>
  1478. /// <paramref name="name"/> is an empty string.
  1479. /// </para>
  1480. /// <para>
  1481. /// -or-
  1482. /// </para>
  1483. /// <para>
  1484. /// <paramref name="name"/> is a string of spaces.
  1485. /// </para>
  1486. /// <para>
  1487. /// -or-
  1488. /// </para>
  1489. /// <para>
  1490. /// <paramref name="name"/> contains an invalid character.
  1491. /// </para>
  1492. /// <para>
  1493. /// -or-
  1494. /// </para>
  1495. /// <para>
  1496. /// <paramref name="name"/> is a restricted header name.
  1497. /// </para>
  1498. /// </exception>
  1499. /// <exception cref="InvalidOperationException">
  1500. /// This instance does not allow the header.
  1501. /// </exception>
  1502. public override void Remove (string name)
  1503. {
  1504. name = checkName (name, "name");
  1505. var headerType = getHeaderType (name);
  1506. checkRestricted (name, headerType);
  1507. checkAllowed (headerType);
  1508. base.Remove (name);
  1509. }
  1510. /// <summary>
  1511. /// Sets the specified request header to the specified value.
  1512. /// </summary>
  1513. /// <param name="header">
  1514. /// <para>
  1515. /// One of the <see cref="HttpRequestHeader"/> enum values.
  1516. /// </para>
  1517. /// <para>
  1518. /// It specifies the request header to set.
  1519. /// </para>
  1520. /// </param>
  1521. /// <param name="value">
  1522. /// A <see cref="string"/> that specifies the value of the request header
  1523. /// to set.
  1524. /// </param>
  1525. /// <exception cref="ArgumentException">
  1526. /// <para>
  1527. /// <paramref name="value"/> contains an invalid character.
  1528. /// </para>
  1529. /// <para>
  1530. /// -or-
  1531. /// </para>
  1532. /// <para>
  1533. /// <paramref name="header"/> is a restricted header.
  1534. /// </para>
  1535. /// </exception>
  1536. /// <exception cref="ArgumentOutOfRangeException">
  1537. /// The length of <paramref name="value"/> is greater than 65,535
  1538. /// characters.
  1539. /// </exception>
  1540. /// <exception cref="InvalidOperationException">
  1541. /// This instance does not allow the request header.
  1542. /// </exception>
  1543. public void Set (HttpRequestHeader header, string value)
  1544. {
  1545. value = checkValue (value, "value");
  1546. var key = header.ToString ();
  1547. var name = getHeaderName (key);
  1548. checkRestricted (name, HttpHeaderType.Request);
  1549. checkAllowed (HttpHeaderType.Request);
  1550. set (name, value, HttpHeaderType.Request);
  1551. }
  1552. /// <summary>
  1553. /// Sets the specified response header to the specified value.
  1554. /// </summary>
  1555. /// <param name="header">
  1556. /// <para>
  1557. /// One of the <see cref="HttpResponseHeader"/> enum values.
  1558. /// </para>
  1559. /// <para>
  1560. /// It specifies the response header to set.
  1561. /// </para>
  1562. /// </param>
  1563. /// <param name="value">
  1564. /// A <see cref="string"/> that specifies the value of the response header
  1565. /// to set.
  1566. /// </param>
  1567. /// <exception cref="ArgumentException">
  1568. /// <para>
  1569. /// <paramref name="value"/> contains an invalid character.
  1570. /// </para>
  1571. /// <para>
  1572. /// -or-
  1573. /// </para>
  1574. /// <para>
  1575. /// <paramref name="header"/> is a restricted header.
  1576. /// </para>
  1577. /// </exception>
  1578. /// <exception cref="ArgumentOutOfRangeException">
  1579. /// The length of <paramref name="value"/> is greater than 65,535
  1580. /// characters.
  1581. /// </exception>
  1582. /// <exception cref="InvalidOperationException">
  1583. /// This instance does not allow the response header.
  1584. /// </exception>
  1585. public void Set (HttpResponseHeader header, string value)
  1586. {
  1587. value = checkValue (value, "value");
  1588. var key = header.ToString ();
  1589. var name = getHeaderName (key);
  1590. checkRestricted (name, HttpHeaderType.Response);
  1591. checkAllowed (HttpHeaderType.Response);
  1592. set (name, value, HttpHeaderType.Response);
  1593. }
  1594. /// <summary>
  1595. /// Sets the specified header to the specified value.
  1596. /// </summary>
  1597. /// <param name="name">
  1598. /// A <see cref="string"/> that specifies the name of the header to set.
  1599. /// </param>
  1600. /// <param name="value">
  1601. /// A <see cref="string"/> that specifies the value of the header to set.
  1602. /// </param>
  1603. /// <exception cref="ArgumentNullException">
  1604. /// <paramref name="name"/> is <see langword="null"/>.
  1605. /// </exception>
  1606. /// <exception cref="ArgumentException">
  1607. /// <para>
  1608. /// <paramref name="name"/> is an empty string.
  1609. /// </para>
  1610. /// <para>
  1611. /// -or-
  1612. /// </para>
  1613. /// <para>
  1614. /// <paramref name="name"/> is a string of spaces.
  1615. /// </para>
  1616. /// <para>
  1617. /// -or-
  1618. /// </para>
  1619. /// <para>
  1620. /// <paramref name="name"/> contains an invalid character.
  1621. /// </para>
  1622. /// <para>
  1623. /// -or-
  1624. /// </para>
  1625. /// <para>
  1626. /// <paramref name="value"/> contains an invalid character.
  1627. /// </para>
  1628. /// <para>
  1629. /// -or-
  1630. /// </para>
  1631. /// <para>
  1632. /// <paramref name="name"/> is a restricted header name.
  1633. /// </para>
  1634. /// </exception>
  1635. /// <exception cref="ArgumentOutOfRangeException">
  1636. /// The length of <paramref name="value"/> is greater than 65,535
  1637. /// characters.
  1638. /// </exception>
  1639. /// <exception cref="InvalidOperationException">
  1640. /// This instance does not allow the header.
  1641. /// </exception>
  1642. public override void Set (string name, string value)
  1643. {
  1644. name = checkName (name, "name");
  1645. value = checkValue (value, "value");
  1646. var headerType = getHeaderType (name);
  1647. checkRestricted (name, headerType);
  1648. checkAllowed (headerType);
  1649. set (name, value, headerType);
  1650. }
  1651. /// <summary>
  1652. /// Converts the current instance to an array of byte.
  1653. /// </summary>
  1654. /// <returns>
  1655. /// An array of <see cref="byte"/> converted from a string that represents
  1656. /// the current instance.
  1657. /// </returns>
  1658. public byte[] ToByteArray ()
  1659. {
  1660. return Encoding.UTF8.GetBytes (ToString ());
  1661. }
  1662. /// <summary>
  1663. /// Returns a string that represents the current instance.
  1664. /// </summary>
  1665. /// <returns>
  1666. /// A <see cref="string"/> that represents all headers in the collection.
  1667. /// </returns>
  1668. public override string ToString ()
  1669. {
  1670. var cnt = Count;
  1671. if (cnt == 0)
  1672. return "\r\n";
  1673. var buff = new StringBuilder ();
  1674. for (var i = 0; i < cnt; i++)
  1675. buff.AppendFormat ("{0}: {1}\r\n", GetKey (i), Get (i));
  1676. buff.Append ("\r\n");
  1677. return buff.ToString ();
  1678. }
  1679. #endregion
  1680. #region Explicit Interface Implementations
  1681. /// <summary>
  1682. /// Populates a <see cref="SerializationInfo"/> instance with the data
  1683. /// needed to serialize this instance.
  1684. /// </summary>
  1685. /// <param name="serializationInfo">
  1686. /// A <see cref="SerializationInfo"/> to populate with the data.
  1687. /// </param>
  1688. /// <param name="streamingContext">
  1689. /// A <see cref="StreamingContext"/> that specifies the destination for
  1690. /// the serialization.
  1691. /// </param>
  1692. /// <exception cref="ArgumentNullException">
  1693. /// <paramref name="serializationInfo"/> is <see langword="null"/>.
  1694. /// </exception>
  1695. [
  1696. SecurityPermission (
  1697. SecurityAction.LinkDemand,
  1698. Flags = SecurityPermissionFlag.SerializationFormatter,
  1699. SerializationFormatter = true
  1700. )
  1701. ]
  1702. void ISerializable.GetObjectData (
  1703. SerializationInfo serializationInfo, StreamingContext streamingContext
  1704. )
  1705. {
  1706. GetObjectData (serializationInfo, streamingContext);
  1707. }
  1708. #endregion
  1709. }
  1710. }