/// <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);
 }
Пример #2
0
        // 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);
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        /// <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));
        }
Пример #5
0
        /// <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));
                }
            }
        }
Пример #6
0
        /// <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());
            }
        }
Пример #7
0
        /// <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);
        }