HttpLibrary and multipart/form-data messages Boundaries are altered

1,586 views
Skip to first unread message

gwal...@navinet.net

unread,
Jun 21, 2013, 11:18:24 AM6/21/13
to robotframe...@googlegroups.com
When I send a HTTP Post request using httpLibrary of a multi-part form data message type the additional boundaries get added which corrupts the message:
When I sent the message to Fiddler this is what I get:

The boundary am I using is 8d030e3574841ed
The extra content added by http library is ------------a_BoUnDaRy622531459405$




POST http://127.0.0.1:8888/ClinicalDataService/api/Documents HTTP/1.1
Accept-Encoding: identity
Host: 127.0.0.1:8888
Content-Type: multipart/form-data;boundary=8d030e3574841ed
Content-Length: 43732

------------a_BoUnDaRy622531459405$
Content-Disposition: form-data; name="
--8d030e3574841ed
Content-Disposition: form-data"


------------a_BoUnDaRy622531459405$
Content-Disposition: form-data; name=" name"

"metadata"
Content-Type: application/json


Kevin O.

unread,
Jun 26, 2013, 9:03:15 AM6/26/13
to robotframe...@googlegroups.com
Could you post some code so we can see how you are using the library?

gwal...@navinet.net

unread,
Jul 3, 2013, 8:52:14 AM7/3/13
to robotframe...@googlegroups.com


On Wednesday, 26 June 2013 14:03:15 UTC+1, Kevin O. wrote:
Could you post some code so we can see how you are using the library?


*** Test Cases ***
POST to Service
    [Documentation]    This test does an HTTP Post
    HTTP Post to HTTP Endpoint    ${HOST}    ${URL}    data\\testDocument.json    UTF-8    Content-Type    multipart/form-data;boundary=8d030e3574841ed
    ...    200

*** Keywords ***
HTTP Post to HTTP Endpoint
    [Arguments]    ${HOST}    ${URL}    ${xmlFilename}    ${Request_Body_Encoding}    ${HeaderName}    ${HeaderValue}
    ...    ${ResponseStatusCode}
    [Documentation]    Executes an HTTP POST against the Clinical Data Service.
    ...
    ...    ${HOST} - Hostname of the server
    ...    ${URL} - URL of the Service eg. /DataService/Documents
    ...    ${filename} - Path and filename of the body used in the POST eg. Data\\testDocument.json
    ...    ${Request_Body_Encoding} - Encoding used for the body of the request eg. \ UTF-8
    ...    ${HeaderType} - Header Type used in the request eg. Content-Type
    ...    ${Header_Encoding} - Header Encoding used in the request eg. multipart form data
    ...    ${ResponseStatusCode} - HTTP Response Code expected from the server eg. 200
    ...
    Create HTTP Context    ${HOST}    http
    ${Request_Body}    Get File    ${filename}    encoding=${Request_Body_Encoding}
    Set Request Header    ${HeaderName}    ${HeaderValue}
    Set Request Body    ${Request_Body}
    Log    ${Request_Body}
    POST    ${URL}
    Response Status Code Should Equal    ${ResponseStatusCode}


*** Variables ***


${PORT}     80
${PROTOCOL}        http://
${URL}        /DataService/api/Documents
${HOST}     127.0.0.1

Kevin O.

unread,
Jul 3, 2013, 3:19:42 PM7/3/13
to robotframe...@googlegroups.com
This looks like a defect in HttpLibrary. Please report it.
If Content-Type is sent as a header to livetest's post method without using content_type argument, the body is not altered.
HttpLibrary is detecting this header and passing the value that through to the content_type arg.
webtest.TestApp._gen_request tries to add a file into the body if content_type is sent and it starts with 'multipart'.
The lines that are causing the problem are:

    if 'Content-Type' in self.context.request_headers:
    kwargs['content_type'] = self.context.request_headers['Content-Type']

I'm not sure why this was done as adding a 'Content-Type' request header seems sufficient to make a proper request.

You could:
monkey patch HttpLibrary (works but have to make sure the monkey patch is loaded before RF creates an instance of HttpLibrary)
call an alternate keyword in a library that extends HttpLibrary
extend the library through inheritence and use your library instead of HttpLibrary
comment out the problematic lines in the source code (bad idea)

Seems like there should be a Add Attachment keyword that allows you to attach files to the request and let webtest handle building multipart messages.

Option 2 shown below (kw is called post_raw for lack of a better name):

from robot.libraries.BuiltIn import BuiltIn
from robot.api import logger

def post_raw(url):
    """
    Issues a HTTP POST request.

    `url` is the URL relative to the server root, e.g. '/_utils/config.html'
    """
    self = BuiltIn().get_library_instance('HttpLibrary.HTTP')
    path = self._path_from_url_or_path(url)
    kwargs = {}
    logger.debug("Performing POST request on %s://%s%s" % (self.context._scheme, self.app.host, url))
    self.context.pre_process_request()
    self.context.post_process_request(
      self.app.post(path, self.context.request_body or {}, self.context.request_headers, **kwargs)
    )

Almost Two

unread,
Oct 11, 2016, 2:59:58 PM10/11/16
to robotframework-users
Hello Kevin,

Thanks for your support on this.

After use the Post Raw keyword i got the following message

Keyword 'HttpLibrary.HTTP.Post Raw' expected 0 arguments, got 1.

Post Raw    /api/Document/

How do you recommend to use this kw?
Reply all
Reply to author
Forward
0 new messages