简体   繁体   中英

How to properly send a multipart/form-data using an http GET request in jmeter

I have an Apache server that I am trying to load test using a JMeter. There is a situation that causes our server to crash when it is receiving certain kinds of requests. One of these is a GET request with an attachment. If I test the connection using curl it works fine. Here is a sample curl string that I am using:

$ curl -X GET --connect-timeout 5 -m 600 -Y 200 -y 60 -F filename="@archives_x2cok01241201_.tar.gz" "http://172.17.0.150:8080/ckmp-ivc/IFEDataOffload?tailid=efxdom06281201&type=t&version=DL_X_FS_20120607&checksum=908022653&tailname=DL000"

And this is what I see with WireShark:

13  2.567406    172.17.0.102    172.17.0.150    HTTP    GET /ckmp-ivc/IFEDataOffload?tailid=efxdom06281201&type=t&version=DL_X_FS_20120607&checksum=908022653&tailname=DL000 HTTP/1.1  (application/octet-stream)

On the serverside, the log shows me a valid request.

However, when I try to make the same request using JMeter. It doesn't work and the server says that:

java.io.IOException: Posted content type isn't multipart/form-data

When I look at the JMeter connection inside WireShark I see:

177 157.326959  172.17.0.102    172.17.0.150    HTTP    GET /ckmp-ivc/IFEDataOffload?tailid=efxdom02071201&type=t&version=DL_X_FS_201202&checksum=908022653&tailname=DL000 HTTP/1.1 

Notice that the "(application/octet-stream)" from the curl request is missing in the JMeter request when viewed from WireShark.

I have tried every variation of MIMEType (mime_multipart, multipart/form-data, etc) I can think of to no avial. I have also tried every content encoding (application/octet-stream, application/binary, etc) I can think of but nothing seems to work. The attachment never makes it to the server. I am stumped on how to proceed.

I have also tried to use JMeter HTTIP Recorder / HTTP Proxy to capture the curl request. However, it doesn't seem to handle my code correctly. When I run curl through the JMeter proxy such as by:

$ curl -x localhost:8080 -X GET --connect-timeout 5 -m 600 -Y 200 -y 60 -F filename="@archives_x2cok01241201_.tar.gz" "http://172.17.0.150:8080/ckmp-ivc/IFEDataOffload?tailid=efxdom06281201&type=t&version=DL_X_FS_20120607&checksum=908022653&tailname=DL000"

The request fails to go through properly which makes me think that the Recorder can't handle this jsp code properly. The end result is the same as the regular JMeter call with no (applicaiton/octet-stream) at the end of the WireShark Capture. The Recorder does manage to add an HTTP Header Manager with the following Headers:

Content-Type multipart/form-data; boundary=------------------------56e0b872879ebd54 Expect 100-continue Accept / User-Agent curl/7.32.0

However, the file to be added with the request is missing.

I am completely baffled on how to proceed. Does anyone know what I am doing wrong? Does this functionality not work in JMeter? Does anyone know of a good example that I can use as a reference?

I have searched repeatedly here and on google but I am not coming up with anything that matches this question. Any help would be greatly appreciated.

Below is my JMeter Test Plan:

<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="2.5" jmeter="2.10 r1533061">
  <hashTree>
    <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
      <stringProp name="TestPlan.comments"></stringProp>
      <boolProp name="TestPlan.functional_mode">false</boolProp>
      <boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
      <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
        <collectionProp name="Arguments.arguments"/>
      </elementProp>
      <stringProp name="TestPlan.user_define_classpath"></stringProp>
    </TestPlan>
    <hashTree>
      <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group - Tails - Test" enabled="true">
        <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
        <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
          <boolProp name="LoopController.continue_forever">false</boolProp>
          <stringProp name="LoopController.loops">1</stringProp>
        </elementProp>
        <stringProp name="ThreadGroup.num_threads">1</stringProp>
        <stringProp name="ThreadGroup.ramp_time">1</stringProp>
        <longProp name="ThreadGroup.start_time">1362651221000</longProp>
        <longProp name="ThreadGroup.end_time">1362651221000</longProp>
        <boolProp name="ThreadGroup.scheduler">false</boolProp>
        <stringProp name="ThreadGroup.duration"></stringProp>
        <stringProp name="ThreadGroup.delay"></stringProp>
      </ThreadGroup>
      <hashTree>
        <ConfigTestElement guiclass="HttpDefaultsGui" testclass="ConfigTestElement" testname="HTTP Request Defaults" enabled="true">
          <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
            <collectionProp name="Arguments.arguments"/>
          </elementProp>
          <stringProp name="HTTPSampler.domain">172.17.0.150</stringProp>
          <stringProp name="HTTPSampler.port">8080</stringProp>
          <stringProp name="HTTPSampler.connect_timeout">30000</stringProp>
          <stringProp name="HTTPSampler.response_timeout">30000</stringProp>
          <stringProp name="HTTPSampler.protocol">http</stringProp>
          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
          <stringProp name="HTTPSampler.path"></stringProp>
          <stringProp name="HTTPSampler.concurrentPool">4</stringProp>
        </ConfigTestElement>
        <hashTree/>
        <CSVDataSet guiclass="TestBeanGUI" testclass="CSVDataSet" testname="CSV Data Set Config" enabled="true">
          <stringProp name="filename">C:\Test\Tail_info_efx.csv</stringProp>
          <stringProp name="fileEncoding"></stringProp>
          <stringProp name="variableNames">tailid,ipaddress,version,checksum,keystring,confignum,adsuffix</stringProp>
          <stringProp name="delimiter">,</stringProp>
          <boolProp name="quotedData">true</boolProp>
          <boolProp name="recycle">true</boolProp>
          <boolProp name="stopThread">true</boolProp>
          <stringProp name="shareMode">shareMode.all</stringProp>
        </CSVDataSet>
        <hashTree/>
        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="IFEDataOffload - hardcoded" enabled="true">
          <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
            <collectionProp name="Arguments.arguments">
              <elementProp name="tailid" elementType="HTTPArgument">
                <boolProp name="HTTPArgument.always_encode">false</boolProp>
                <stringProp name="Argument.value">efxdom02071201</stringProp>
                <stringProp name="Argument.metadata">=</stringProp>
                <boolProp name="HTTPArgument.use_equals">true</boolProp>
                <stringProp name="Argument.name">tailid</stringProp>
              </elementProp>
              <elementProp name="type" elementType="HTTPArgument">
                <boolProp name="HTTPArgument.always_encode">false</boolProp>
                <stringProp name="Argument.value">t</stringProp>
                <stringProp name="Argument.metadata">=</stringProp>
                <boolProp name="HTTPArgument.use_equals">true</boolProp>
                <stringProp name="Argument.name">type</stringProp>
              </elementProp>
              <elementProp name="version" elementType="HTTPArgument">
                <boolProp name="HTTPArgument.always_encode">false</boolProp>
                <stringProp name="Argument.value">DL_X_FS_201202</stringProp>
                <stringProp name="Argument.metadata">=</stringProp>
                <boolProp name="HTTPArgument.use_equals">true</boolProp>
                <stringProp name="Argument.name">version</stringProp>
              </elementProp>
              <elementProp name="checksum" elementType="HTTPArgument">
                <boolProp name="HTTPArgument.always_encode">false</boolProp>
                <stringProp name="Argument.value">908022653</stringProp>
                <stringProp name="Argument.metadata">=</stringProp>
                <boolProp name="HTTPArgument.use_equals">true</boolProp>
                <stringProp name="Argument.name">checksum</stringProp>
              </elementProp>
              <elementProp name="tailname" elementType="HTTPArgument">
                <boolProp name="HTTPArgument.always_encode">false</boolProp>
                <stringProp name="Argument.value">DL000</stringProp>
                <stringProp name="Argument.metadata">=</stringProp>
                <boolProp name="HTTPArgument.use_equals">true</boolProp>
                <stringProp name="Argument.name">tailname</stringProp>
              </elementProp>
            </collectionProp>
          </elementProp>
          <stringProp name="HTTPSampler.domain"></stringProp>
          <stringProp name="HTTPSampler.port"></stringProp>
          <stringProp name="HTTPSampler.connect_timeout"></stringProp>
          <stringProp name="HTTPSampler.response_timeout"></stringProp>
          <stringProp name="HTTPSampler.protocol"></stringProp>
          <stringProp name="HTTPSampler.contentEncoding">multipart/form-data</stringProp>
          <stringProp name="HTTPSampler.path">/ckmp-ivc/IFEDataOffload</stringProp>
          <stringProp name="HTTPSampler.method">GET</stringProp>
          <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
          <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
          <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
          <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
          <stringProp name="HTTPSampler.implementation">Java</stringProp>
          <elementProp name="HTTPsampler.Files" elementType="HTTPFileArgs">
            <collectionProp name="HTTPFileArgs.files">
              <elementProp name="C:\Test\archives_efxdom02071201_.tar.gz" elementType="HTTPFileArg">
                <stringProp name="File.path">C:\Test\archives_efxdom02071201_.tar.gz</stringProp>
                <stringProp name="File.paramname">filename</stringProp>
                <stringProp name="File.mimetype">mime_multipart</stringProp>
              </elementProp>
            </collectionProp>
          </elementProp>
          <boolProp name="HTTPSampler.monitor">false</boolProp>
          <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
        </HTTPSamplerProxy>
        <hashTree/>
        <ResultCollector guiclass="TableVisualizer" testclass="ResultCollector" testname="View Results in Table" enabled="true">
          <boolProp name="ResultCollector.error_logging">false</boolProp>
          <objProp>
            <name>saveConfig</name>
            <value class="SampleSaveConfiguration">
              <time>true</time>
              <latency>true</latency>
              <timestamp>true</timestamp>
              <success>true</success>
              <label>true</label>
              <code>true</code>
              <message>true</message>
              <threadName>true</threadName>
              <dataType>true</dataType>
              <encoding>false</encoding>
              <assertions>true</assertions>
              <subresults>true</subresults>
              <responseData>false</responseData>
              <samplerData>false</samplerData>
              <xml>true</xml>
              <fieldNames>false</fieldNames>
              <responseHeaders>false</responseHeaders>
              <requestHeaders>false</requestHeaders>
              <responseDataOnError>false</responseDataOnError>
              <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
              <assertionsResultsToSave>0</assertionsResultsToSave>
              <bytes>true</bytes>
            </value>
          </objProp>
          <stringProp name="filename">C:\Test\Results Table</stringProp>
        </ResultCollector>
        <hashTree/>
      </hashTree>
    </hashTree>
  </hashTree>
</jmeterTestPlan>

First of all, read this answer and the whole discussion, it will bring some context. I suppose many client libraries may be implemented with restriction to send message body with GET method. If Apache HTTP Client library have such restriction, then your issue is described. So in general I'd suggest you to use POST method with body instead of GET.

If this is not acceptable for you, you may use RawRequest plugin from jmeter-plugins.org to perform a freeform TCP-request which you'll get via WireShark TCP stream.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM