/// <summary> /// Writes characters from the specified char array followed by a line /// delimiter to this session buffer. /// </summary> /// <remarks> /// Writes characters from the specified char array followed by a line /// delimiter to this session buffer. /// <p> /// This method uses CR-LF as a line delimiter. /// </remarks> /// <param name="charbuffer">the buffer containing chars of the line.</param> /// <exception> /// IOException /// if an I/O error occurs. /// </exception> /// <exception cref="System.IO.IOException"></exception> public virtual void WriteLine(CharArrayBuffer charbuffer) { if (charbuffer == null) { return; } if (this.encoder == null) { int off = 0; int remaining = charbuffer.Length(); while (remaining > 0) { int chunk = this.buffer.Capacity() - this.buffer.Length(); chunk = Math.Min(chunk, remaining); if (chunk > 0) { this.buffer.Append(charbuffer, off, chunk); } if (this.buffer.IsFull()) { FlushBuffer(); } off += chunk; remaining -= chunk; } } else { CharBuffer cbuf = CharBuffer.Wrap(charbuffer.Buffer(), 0, charbuffer.Length()); WriteEncoded(cbuf); } Write(Crlf); }
// non-javadoc, see interface LineParser public virtual bool HasProtocolVersion(CharArrayBuffer buffer, ParserCursor cursor ) { Args.NotNull(buffer, "Char array buffer"); Args.NotNull(cursor, "Parser cursor"); int index = cursor.GetPos(); string protoname = this.protocol.GetProtocol(); int protolength = protoname.Length; if (buffer.Length() < protolength + 4) { return(false); } // not long enough for "HTTP/1.1" if (index < 0) { // end of line, no tolerance for trailing whitespace // this works only for single-digit major and minor version index = buffer.Length() - 4 - protolength; } else { if (index == 0) { // beginning of line, tolerate leading whitespace while ((index < buffer.Length()) && HTTP.IsWhitespace(buffer.CharAt(index))) { index++; } } } // else within line, don't tolerate whitespace if (index + protolength + 4 > buffer.Length()) { return(false); } // just check protocol name and slash, no need to analyse the version bool ok = true; for (int j = 0; ok && (j < protolength); j++) { ok = (buffer.CharAt(index + j) == protoname[j]); } if (ok) { ok = (buffer.CharAt(index + protolength) == '/'); } return(ok); }
/// <summary> /// Returns a list of /// <see cref="Apache.Http.NameValuePair">NameValuePairs</see> /// as parsed from the given string using the given character /// encoding. /// </summary> /// <param name="s">text to parse.</param> /// <param name="charset">Encoding to use when decoding the parameters.</param> /// <param name="parameterSeparator"> /// The characters used to separate parameters, by convention, /// <code>'&'</code> /// and /// <code>';'</code> /// . /// </param> /// <returns> /// a list of /// <see cref="Apache.Http.NameValuePair">Apache.Http.NameValuePair</see> /// as built from the URI's query portion. /// </returns> /// <since>4.3</since> public static IList <NameValuePair> Parse(string s, Encoding charset, params char[] parameterSeparator) { if (s == null) { return(Sharpen.Collections.EmptyList()); } BasicHeaderValueParser parser = BasicHeaderValueParser.Instance; CharArrayBuffer buffer = new CharArrayBuffer(s.Length); buffer.Append(s); ParserCursor cursor = new ParserCursor(0, buffer.Length()); IList <NameValuePair> list = new AList <NameValuePair>(); while (!cursor.AtEnd()) { NameValuePair nvp = parser.ParseNameValuePair(buffer, cursor, parameterSeparator); if (nvp.GetName().Length > 0) { list.AddItem(new BasicNameValuePair(DecodeFormFields(nvp.GetName(), charset), DecodeFormFields (nvp.GetValue(), charset))); } } return(list); }
/// <summary>Parses the Set-Cookie value into an array of <tt>Cookie</tt>s.</summary> /// <remarks> /// Parses the Set-Cookie value into an array of <tt>Cookie</tt>s. /// <p>Syntax of the Set-Cookie HTTP Response Header:</p> /// <p>This is the format a CGI script would use to add to /// the HTTP headers a new piece of data which is to be stored by /// the client for later retrieval.</p> /// <PRE> /// Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure /// </PRE> /// <p>Please note that the Netscape draft specification does not fully conform to the HTTP /// header format. Comma character if present in <code>Set-Cookie</code> will not be treated /// as a header element separator</p> /// </remarks> /// <seealso><a href="http://web.archive.org/web/20020803110822/http://wp.netscape.com/newsref/std/cookie_spec.html"> /// * The Cookie Spec.</a></seealso> /// <param name="header">the <tt>Set-Cookie</tt> received from the server</param> /// <returns>an array of <tt>Cookie</tt>s parsed from the Set-Cookie value</returns> /// <exception cref="Apache.Http.Cookie.MalformedCookieException">if an exception occurs during parsing /// </exception> public override IList <Apache.Http.Cookie.Cookie> Parse(Header header, CookieOrigin origin) { Args.NotNull(header, "Header"); Args.NotNull(origin, "Cookie origin"); if (!Sharpen.Runtime.EqualsIgnoreCase(header.GetName(), SM.SetCookie)) { throw new MalformedCookieException("Unrecognized cookie header '" + header.ToString () + "'"); } NetscapeDraftHeaderParser parser = NetscapeDraftHeaderParser.Default; CharArrayBuffer buffer; ParserCursor cursor; if (header is FormattedHeader) { buffer = ((FormattedHeader)header).GetBuffer(); cursor = new ParserCursor(((FormattedHeader)header).GetValuePos(), buffer.Length( )); } else { string s = header.GetValue(); if (s == null) { throw new MalformedCookieException("Header value is null"); } buffer = new CharArrayBuffer(s.Length); buffer.Append(s); cursor = new ParserCursor(0, buffer.Length()); } return(Parse(new HeaderElement[] { parser.ParseHeader(buffer, cursor) }, origin)); }
/// <exception cref="Apache.Http.Cookie.MalformedCookieException"></exception> public virtual IList <Apache.Http.Cookie.Cookie> Parse(Header header, CookieOrigin origin) { Args.NotNull(header, "Header"); Args.NotNull(origin, "Cookie origin"); HeaderElement[] helems = header.GetElements(); bool versioned = false; bool netscape = false; foreach (HeaderElement helem in helems) { if (helem.GetParameterByName("version") != null) { versioned = true; } if (helem.GetParameterByName("expires") != null) { netscape = true; } } if (netscape || !versioned) { // Need to parse the header again, because Netscape style cookies do not correctly // support multiple header elements (comma cannot be treated as an element separator) NetscapeDraftHeaderParser parser = NetscapeDraftHeaderParser.Default; CharArrayBuffer buffer; ParserCursor cursor; if (header is FormattedHeader) { buffer = ((FormattedHeader)header).GetBuffer(); cursor = new ParserCursor(((FormattedHeader)header).GetValuePos(), buffer.Length( )); } else { string s = header.GetValue(); if (s == null) { throw new MalformedCookieException("Header value is null"); } buffer = new CharArrayBuffer(s.Length); buffer.Append(s); cursor = new ParserCursor(0, buffer.Length()); } helems = new HeaderElement[] { parser.ParseHeader(buffer, cursor) }; return(GetCompat().Parse(helems, origin)); } else { if (SM.SetCookie2.Equals(header.GetName())) { return(GetStrict().Parse(helems, origin)); } else { return(GetObsoleteStrict().Parse(helems, origin)); } } }
/// <exception cref="Apache.Http.Auth.MalformedChallengeException"></exception> protected internal override void ParseChallenge(CharArrayBuffer buffer, int pos, int len) { HeaderValueParser parser = BasicHeaderValueParser.Instance; ParserCursor cursor = new ParserCursor(pos, buffer.Length()); HeaderElement[] elements = parser.ParseElements(buffer, cursor); if (elements.Length == 0) { throw new MalformedChallengeException("Authentication challenge is empty"); } [email protected](); foreach (HeaderElement element in elements) { [email protected](element.GetName(), element.GetValue()); } }
/// <summary> /// Parses HTTP headers from the data receiver stream according to the generic /// format as given in Section 3.1 of RFC 822, RFC-2616 Section 4 and 19.3. /// </summary> /// <remarks> /// Parses HTTP headers from the data receiver stream according to the generic /// format as given in Section 3.1 of RFC 822, RFC-2616 Section 4 and 19.3. /// </remarks> /// <param name="inbuffer">Session input buffer</param> /// <param name="maxHeaderCount"> /// maximum number of headers allowed. If the number /// of headers received from the data stream exceeds maxCount value, an /// IOException will be thrown. Setting this parameter to a negative value /// or zero will disable the check. /// </param> /// <param name="maxLineLen"> /// maximum number of characters for a header line, /// including the continuation lines. Setting this parameter to a negative /// value or zero will disable the check. /// </param> /// <param name="parser">line parser to use.</param> /// <param name="headerLines"> /// List of header lines. This list will be used to store /// intermediate results. This makes it possible to resume parsing of /// headers in case of a /// <see cref="System.Threading.ThreadInterruptedException">System.Threading.ThreadInterruptedException /// </see> /// . /// </param> /// <returns>array of HTTP headers</returns> /// <exception cref="System.IO.IOException">in case of an I/O error</exception> /// <exception cref="Org.Apache.Http.HttpException">in case of HTTP protocol violation /// </exception> /// <since>4.1</since> public static Header[] ParseHeaders(SessionInputBuffer inbuffer, int maxHeaderCount , int maxLineLen, LineParser parser, IList <CharArrayBuffer> headerLines) { Args.NotNull(inbuffer, "Session input buffer"); Args.NotNull(parser, "Line parser"); Args.NotNull(headerLines, "Header line list"); CharArrayBuffer current = null; CharArrayBuffer previous = null; for (; ;) { if (current == null) { current = new CharArrayBuffer(64); } else { current.Clear(); } int l = inbuffer.ReadLine(current); if (l == -1 || current.Length() < 1) { break; } // Parse the header name and value // Check for folded headers first // Detect LWS-char see HTTP/1.0 or HTTP/1.1 Section 2.2 // discussion on folded headers if ((current.CharAt(0) == ' ' || current.CharAt(0) == '\t') && previous != null) { // we have continuation folded header // so append value int i = 0; while (i < current.Length()) { char ch = current.CharAt(i); if (ch != ' ' && ch != '\t') { break; } i++; } if (maxLineLen > 0 && previous.Length() + 1 + current.Length() - i > maxLineLen) { throw new MessageConstraintException("Maximum line length limit exceeded"); } previous.Append(' '); previous.Append(current, i, current.Length() - i); } else { headerLines.AddItem(current); previous = current; current = null; } if (maxHeaderCount > 0 && headerLines.Count >= maxHeaderCount) { throw new MessageConstraintException("Maximum header count exceeded"); } } Header[] headers = new Header[headerLines.Count]; for (int i_1 = 0; i_1 < headerLines.Count; i_1++) { CharArrayBuffer buffer = headerLines[i_1]; try { headers[i_1] = parser.ParseHeader(buffer); } catch (ParseException ex) { throw new ProtocolException(ex.Message); } } return(headers); }