MalformedStreamException when sending multipart http request to Wiremock - servlets

I am using Wiremock (which appears to use jetty) to stub some http responses.
I am sending a multipart http request but Wiremock/jetty responds to with a 500 error and some html which details a MalformedStreamException.
This has only broken since a version upgrade of Wiremock from 2.31.0 to 2.32.0.
I am sending the following request in Postman to my stub endpoint:
Headers
Content-Type: multipart/related; boundary=xxx
Request body
--xxx
Content-Type: text/xml; charset=UTF-8
<?xml version="1.0" encoding="utf-8"?>
<test></test>
--xxx
Content-Type: text/xml; charset=UTF-8
<?xml version="1.0" encoding="utf-8"?>
<test></test>
--xxx--
Error
Caused by: wiremock.org.apache.commons.fileupload.FileUploadException: Stream ended unexpectedly
at wiremock.org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:361)
at com.github.tomakehurst.wiremock.http.multipart.PartParser.parseFrom(PartParser.java:51)
at com.github.tomakehurst.wiremock.servlet.WireMockHttpServletRequestAdapter.getParts(WireMockHttpServletRequestAdapter.java:286)
at com.github.tomakehurst.wiremock.verification.LoggedRequest.createFrom(LoggedRequest.java:71)
at com.github.tomakehurst.wiremock.stubbing.InMemoryStubMappings.serveFor(InMemoryStubMappings.java:88)
at com.github.tomakehurst.wiremock.core.WireMockApp.serveStubFor(WireMockApp.java:226)
at com.github.tomakehurst.wiremock.http.StubRequestHandler.handleRequest(StubRequestHandler.java:57)
at com.github.tomakehurst.wiremock.http.AbstractRequestHandler.handle(AbstractRequestHandler.java:69)
at com.github.tomakehurst.wiremock.servlet.WireMockHandlerDispatchingServlet.service(WireMockHandlerDispatchingServlet.java:142)
at wiremock.javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at wiremock.org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799)
at wiremock.org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1631)
at wiremock.org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:548)
at wiremock.org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
at wiremock.org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440)
at wiremock.org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
at wiremock.org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501)
at wiremock.org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
at wiremock.org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355)
at wiremock.org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at wiremock.org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:763)
at wiremock.org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:146)
... 17 more
Caused by: wiremock.org.apache.commons.fileupload.MultipartStream$MalformedStreamException: Stream ended unexpectedly
at wiremock.org.apache.commons.fileupload.MultipartStream.readHeaders(MultipartStream.java:570)
at wiremock.org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.findNextItem(FileUploadBase.java:1052)
at wiremock.org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:1017)
at wiremock.org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:309)
at wiremock.org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:333)
... 38 more
Can anyone spot anything I am doing wrong or have any suggestions of things to rule out or try?
Could there be a bug in Wiremock or one of its dependences or is my multipart request malformed?
Update
I've opened a bug on Github:
https://github.com/wiremock/wiremock/issues/1973

Related

Why does my Web API return 404 on all resources when called from a Console app?

I have a little Web API, almost directly from the standard VS project template, i.e. Home and Values controllers, and lots of MVC cruft. It is set to run and debug under IIS 10.
I have set up tracing by adding the package Microsoft.AspNet.WebApi.Tracing and the following code in WebApiConfig:
public static void Register(HttpConfiguration config)
{
config.EnableSystemDiagnosticsTracing();
SystemDiagnosticsTraceWriter traceWriter = config.EnableSystemDiagnosticsTracing();
traceWriter.IsVerbose = true;
traceWriter.MinimumLevel = TraceLevel.Debug;
config.Services.Replace(typeof(ITraceWriter), new SimpleTracer());
...
...
}
SimpleTracer is an ITraceWriter that writes to a text file.
When I call the API from outside the VS ecosystem, i.e. from PostMan in Chrome, a bad url, that results in a 404 error message, and the creation of a new trace file if there's not already one. Of I call it from PostMan with a good url, I get the expected result, and a trace of the request in the trace file.
When I call it from my Console app, even with a good url, I still get a 404 error response, and nothing is written to the trace file. I made sure by removing it and IIS doesn't even re-create it when using the .exe client.
If I call it from the compiled .exe from outside VS, I get the same error.
Then, when I set the Web API to use IIS Express, everything works perfectly. Do I need CORS for calls from non-web apps, does IIS need an extra header in this case? What is wrong?
EDIT A: This is the request when I use PostMan, and it returns a 200 and the expected list of strings.
GET /DemoApi/api/values HTTP/1.1
Host: localhost
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: f9454ffc-6a8d-e1ed-1a28-23ed8166e534
and the response and headers:
["value1","value2","value3","value4","value5","value6","value7"]
Cache-Control →no-cache
Content-Length →64
Content-Type →application/json; charset=utf-8
Date →Tue, 13 Dec 2016 06:20:07 GMT
Expires →-1
Pragma →no-cache
Server →Microsoft-IIS/10.0
X-AspNet-Version →4.0.30319
X-Powered-By →ASP.NET
EDIT B: This is the request sent using HttpClient:
GET http://abbeyofthelema/api/values HTTP/1.1
Accept: application/json
Host: abbeyofthelema
Connection: Keep-Alive
The only real difference is that because Fiddler doesn't capture traffic from localhost, I had to use my computer name instead. The same recipient still gets the request.
The response here is:
HTTP/1.1 404 Not Found
Cache-Control: private
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET
Date: Tue, 13 Dec 2016 08:07:25 GMT
Content-Length: 4959
According to Timothy Shields at the following link
Why is HttpClient BaseAddress not working?
You must place a slash at the end of the BaseAddress, and you must not place a slash at the beginning of your relative URI

HTTP header 400 bad request response

I'm trying to test writing correct HTTP headers to understand
the syntax. Here I'm trying to PUT some text into httpbin.org/put and I expect the response body content to be the same.
PUT /HTTP/1.1
Host: httpbin.org
Accept-Language: en-us
Connection: Keep-Alive
Content-type: text/plain
Content-Length: 12
Hello jerome
However I'm getting the following bad request 400 response:
HTTP/1.1 400 Bad Request
Server: nginx
Date: Tue, 01 Mar 2016 12:34:02 GMT
Content-Type: text/html
Content-Length: 166
Connection: close
Response:
<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>
What syntactical errors have I done?
NOTE: newlines are \r\n not \n in the request.
Apparently the correct syntax goes like this for PUT:
PUT /put HTTP/1.1\r\n
Content-Length: 11\r\n
Content-Type: text/plain\r\n
Host: httpbin.org\r\n\r\n
hello lala\n
I believe I didn't say much on how I connected to httpbin.org; it was via sockets in C. So the connection was already established before sending the header + message.
You miss the destination url following the PUT verb, the first line must be:
PUT http://httpbin.org/ HTTP/1.1
This will probably also fail, you need one of their handler urls so they know what to reply with:
PUT http://httpbin.org/put HTTP/1.1
The general form of the first line, or Request Line, in an HTTP request is as follows:
<method> <path component of URL, or absolute URL> HTTP/<Version>\r\n
Where for your example, the method is PUT. Including an absolute URL (so, starting with http:// or https:// is only necessary when connecting to a proxy, because the proxy will then attempt to retrieve that URL, rather than attempt to serve a local resource (as found by the path component).
As presented, the only change you should have needed to make was ensuring there was a space between the / and HTTP/1.1. Otherwise, the path would be "/HTTP/1.1"... which would be a 404, if it weren't already a badly formed request. /HTTP/1.1 being interpreted as a path means the HTTP server that's parsing your request line doesn't find the protocol specifier (the HTTP/1.1 bit) before the terminating \r\n... and that's one example of how 400 response codes are born.
Hope that helped. Consult the HTTP 1.1 RFC (2616), section 5.1 for more information and the official definitions.

Uploading file gets Bad Request from the server

I am trying to send a file using HTTP from a C++ application (no HTML-boxes). The server keeps answering Code 400/ Bad Request.
To keep it simple, I have changed manually the content of the file to a simple string (later on, I will need to upload real binary files).
the POST request is the following:
POST /post.php HTTP/1.0
Host: posttestserver.com
Accept: */*
Content-Type: multipart/form-data; boundary=BOUNDARY
--BOUNDARY
Content-Disposition: form-data; name="userfile"; filename="example.txt"
Content-Type:text/plain
123ABC
--BOUNDARY--
Connection: close
Any idea what is going on?

Change Response from HTTP Request sent by a program

I have a program that activate an chip for racing results. (Its just a piece of hardware).
I watch with Fiddler (Sniffing program) the in and outgoing traffic from my pc when I connect the chip with my computer.
The program sends the following HTTP Request:
POST http://example.com/index.php HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Content-Length: 185
Content-Type: application/x-www-form-urlencoded
Host: example.com
Pragma: no-cache
User-Agent: SomeProgram 1.2.3
Data==%0D%0AAjlFNEEw-SOMELONGSECRETKEY-RGAw%3D%3D%0D%0A
I receive the following response:
<?xml version="1.0" encoding="utf-8"?>
<message type="3" result="1" txid="someid" activationdate="" availablecredits="732" firstname="John" lastname="Doe" email="JohnDoe#outlook.com" phonenumber="00123445" notification_email="1" notification_text="1"/>
Is it possible to edit the response so that when the programs check for the availablecredits variable, he get the value 9999 instead of 732.
Im working on a Windows 8 laptop.
Definitely - Fiddler allows you to modify requests and responses by adding rules to FiddlerScript. Citing Fiddler documentation:
To make custom changes to web requests and responses, use
FiddlerScript to add rules to Fiddler's OnBeforeRequest or
OnBeforeResponse function. Which function is appropriate depends on
the objects your code uses: OnBeforeRequest is called before each
request, and OnBeforeResponse is called before each response.
So, all you have to do is to add to OnBeforeResponse the logic for replacing the availablecredits attribute value with any value you desire.

asp.net web service return invalid XML

i have a web service its run locally, but when i hosted on AWS its not running from my client I get the error "System.ServiceModel.ProtocolException: There is a problem with the XML ..."
I tried to call it from SoapUI its working
this is the request :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:her="http://HerakiNet.com/">
<soapenv:Header/>
<soapenv:Body>
<her:SayHello>
<!--Optional:-->
<her:name>Ahmed</her:name>
</her:SayHello>
</soapenv:Body>
</soapenv:Envelope>
and the response as raw:
HTTP/1.0 200 OK
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Date: Sun, 29 Dec 2013 11:12:39 GMT
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Content-Length: 359
X-Cache: MISS from UB15-WMJ-080811
Via: 1.1 UB15-WMJ-080811:3128 (Lusca)
Connection: keep-alive
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><SayHelloResponse xmlns="http://HerakiNet.com/"><SayHelloResult>Hello , Ahmed</SayHelloResult></SayHelloResponse></soap:Body></soap:Envelope>
can any one help??
this is the result of executing a small test from DotNet App:
System.ServiceModel.ProtocolException: There is a problem with the XML that was
received from the network. See inner exception for more details. ---> System.Xml
.XmlException: The data at the root level is invalid. Line 1, position 1 ...
the application code is:
var client = new EstimatorWcfService.EstimatorWebServiceSoapClient();
Console.WriteLine(client.SayHello("Ahmed"));
According to error, you are calling wrong end point url from your client.
There would be two urls in service tag in your wsdl one for http and another for https. May be you are using https one instead of http. Cross check from soap ui (at top of your request).

Resources