This commit fixes problems where logging frameworks, the REPL, etc. could create massive strings representing gigantic JSON arrays. After this change, only the top-level class will be printed, e.g. JArray(<12452 values>) To generate an actual JSON string, use renderCompact (to minimize the size of JSON produced), renderPretty (for whitespace and indentation), or renderCanonical (like renderPretty but also sorts fields in JObject to assist string equality testing).
HttpClientXLightWeb sends text/plain for the Content-Type header if the request body is empty, even if some other content-type is specified. This changes the jvalue combinator to be lenient with respect to content-type if the request body is in fact empty.
Previously, ByteChunk was defined as: Either[ByteBuffer, StreamT[Future, ByteBuffer]]. This meant that users had to be *very* careful to avoid evaluating ByteChunks in parallel, since the underlying ByteBuffer's position fields are mutable and are changed by reads. The new definition is: Either[Array[Byte], StreamT[Future, Array[Byte]]] While the underlying data is itself mutable, the act of reading the data will not modify the array. This should remove a whole class of possible errors, and make it much easier to write correct request combinators.
Conflicts: json/src/main/scala/blueeyes/json/AsyncParser.scala json/src/test/scala/blueeyes/json/JsonParserSpec.scala
The async parser was introduced to handle a very specific use case: parsing a (whitespace delimited) stream of relatively small (<1M) JSON objects. Its design, buffering strategy, and strategy for resuming parsing were all based on this scenario. In scenarios where the user wanted to use many small chunks to parse a much larger value (i.e. 60M) parser performance would degrate horribly compared to the synchronous (all-at-once) parser. Furthermore, the error-recovery strategy was based around similar assumptions, and was not reliable in general (without frim commitments from the user about delimiters and escaping it is hard to see how it could be). This commit does several things: 1. Fix the major performance problems seen when async parsing one large value. While this is still not an ideal situation, performance is now roughly on-par with the equivalent sync parser. 2. Remove the error-recovery option for the AsyncParser. It didn't work reliably and was not being relied on by anyone. 3. Create 3 different async parsing modes: a. Streaming: This is the existing behavior (returning a collection of whitespace-delimited JSON values). b. Json: This mode expects the input to be a single well-formed JSON value. In the future this should become the default behavior. c. Unwrapping: This mode is like (b) but if the JSON value is an array, the parser will instead parse the contents of the array as a stream and return those values, rather than the outer array. Mode (c) is especially exciting, since for situations where users need to parse very large arrays of values. Unlike the sync parser (or the async parser in modes (a) and (b)) unwrapping means that the parser itself does not need to accumulate and store all the parsed objects itself. 4. The commit adds some additional tests and benchmarks to measure the performance of these parsers. None of the synchronous parsers should be affected by these changes.
…gle_responsibility Conflicts: core/src/main/scala/blueeyes/core/service/HttpServerModule.scala core/src/main/scala/blueeyes/core/service/HttpServices.scala core/src/test/scala/blueeyes/core/service/HttpRequestHandlerCombinatorsSpec.scala
… be handled through the exception channel.
Previously, error responses generated by HttpException could overflow the maximum HTTP line length because error messages were being written into the status line. This change modifies error handling to always use Content-Type: text/plain for error responses generated as a result of HttpExceptions (and other sorts of exceptions) thrown during request processing. It is important to note that we have to use text/plain since at the point of handling, no semantic information about the type of the response is available. So, HttpException should *only* ever be used for fatal errors that are not part of the defined API for a given service.
…n of extractors.
… the PML pattern.
Previously, an AsyncParser would try to accumulate as many parse errors as possible using a newline-based error recovery strategy. This change introduces a failFast Boolean constructor parameter. When true, an async parsing result will return at most one error, and no further parsing attempt will be made. When false, the previous behavior will be used. Note that the error-recovery is only intended to help users quickly diagnose and fix bad JSON. The results when using error-recovery are not well-defined unless users delimit their records with literal newlines (and do not use literal newlines anywhere else).