Skip to Content
avatar image
Former Member

XSJS proxy for file uploads via POST request

Hello,

I have a Document Service that I can upload to, view and delete from via multipart POST requests containing a data file to a proxy bridge Java application (following this page).

I want to create an xsjs service to act as a proxy between my UI5 application and the Document Service so I can abstract the Document Service authentication to a xshttpdest file and also populate/maintain a document catalog on our database. I have tried redirecting the original POST request to an xsjs service, crafting my own $.web.WebRequest that points to the Document Service and destination file and copying over the entities, parameters, etc. from the original request. (code below)

This is partly working, and it creates a cmis object on the Document Service with the metadata fields (name, etc), but not the file contents. I suspect the issue to be related to setting the bodies on the entities which contains the file data. Copying the entity bodies from the $.request object to the WebRequest objects entity list using the setBody method does not seem to be working. When I try to evaluate the body of any of these entities, I get an error with message "WebEntityRequest.body: not supported".

I have also tried changing the headers in the incoming $.request to point to our Document Service URI but the XSJS API does not allow the set method on '$.request.headers'.

Am I using the setBody method incorrectly here? Or is there a better way of approaching this? Would greatly appreciate any input or assistance!

Tester HTML (to be done in UI5):

<html>
  <head>
    <title>File Upload Tester</title>
    <script type="text/javascript">
      function setFilename() {
        var thefile = document.getElementById('filename').value.split('\\').pop();
        document.getElementById("cmisname").value = thefile;
      }
    </script>
  </head>
  <body>
    Upload a file to the document service (browse, then press upload)
    <p>
      Please specify a file:<br>
    </p>
    <form action=".../document.xsjs" enctype="multipart/form-data" method="post">
      <div>
        <input type="file" id="filename" onchange="setFilename()" name="datafile" size="40">
        <br><br>
        <input name="cmisaction" type="hidden" value="createDocument" />
        <input name="propertyId[0]" type="hidden" value="cmis:objectTypeId" />
        <input name="propertyValue[0]" type="hidden" value="cmis:document" />
        <input name="propertyId[1]" type="hidden" value="cmis:name" />
        <input name="propertyValue[1]" type="hidden" id="cmisname" />
        <input type="submit" value="Upload">
      </div>
    </form>
  </body>
</html>

document.xsjs:

var dest_pkg = "...";
var dest_name = "...";
var dest_path = ".../[repo_key]/root";


try {
    var dest = $.net.http.readDestination(dest_pkg, dest_name);
    var req = new $.web.WebRequest($.net.http.POST, dest_path);
    var client = new $.net.http.Client();
    
    var i;
    var j;
    for(i = 0; i < $.request.entities.length; i ++) {
        // Create blank entity
        req.entities.create();
        
        // Copy original contentType
        if ($.request.entities[i].contentType !== undefined) {
            req.entities[i].contentType = $.request.entities[i].contentType;   
        }
        
        // Copy original entitiy headers
        for(j = 0; j < $.request.entities[i].headers.length; j ++) {
            req.entities[i].headers.set($.request.entities[i].headers[j].name, $.request.entities[i].headers[j].value);
        }
        
        // Copy original entitiy parameters
        for(j = 0; j < $.request.entities[i].parameters.length; j ++) {
            req.entities[i].parameters.set($.request.entities[i].parameters[j].name, $.request.entities[i].parameters[j].value);
        }
        
        // Copy original entitiy body
        if ($.request.entities[i].body !== undefined) {
            req.entities[i].setBody($.request.entities[i].body.asArrayBuffer());
        }
    }
    
    // Copy original parameters
    for (i = 0; i < $.request.parameters.length; i ++) {
        req.parameters.set($.request.parameters[i].name, $.request.parameters[i].value);
    }
    
    client.request(req, dest);
    var res = client.getResponse();


    $.response.contentType = "application/json";
    $.response.setBody(res.body.asString());
    $.response.status = $.net.http.OK;
} catch (e) {
    $.response.contentType = "text/plain";
    $.response.setBody(e.message);
}
Add comment
10|10000 characters needed characters exceeded

  • Get RSS Feed

2 Answers

  • Best Answer
    avatar image
    Former Member
    Dec 19, 2017 at 04:01 AM

    Got it. I had forgotten to set the contentType property on the WebRequest object to "multiplart/form-data".

    Add comment
    10|10000 characters needed characters exceeded

  • Dec 25, 2017 at 01:35 PM

    I'm trying to use this technique to upload a file via Service Layer "Attachments2" ,it works fine via Postman, but as I convert it to Ajax, I get error:


    {"status":502,"cookies":[],"headers":[{"name":"~response_line","value":"HTTP/1.1 502 Proxy Error"},{"name":"~server_protocol","value":"HTTP/1.1"},{"name":"~status_code","value":"502"},{"name":"~status_reason","value":"Proxy Error"},{"name":"date","value":"Mon, 25 Dec 2017 13:20:09 GMT"},{"name":"server","value":"Apache/2.4.25 (Unix) OpenSSL/0.9.8j-fips"},{"name":"content-length","value":"429"},{"name":"content-type","value":"text/html; charset=iso-8859-1"}],"body":"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n<title>502 Proxy Error</title>\n</head><body>\n<h1>Proxy Error</h1>\n<p>The proxy server received an invalid\r\nresponse from an upstream server.<br />\r\nThe proxy server could not handle the request <em><a href=\"/b1s/v1/Attachments2('2')\">PATCH /b1s/v1/Attachments2('2')</a></em>.<p>\nReason: <strong>Error reading from remote server</strong></p></p>\n</body></html>\n"
    Add comment
    10|10000 characters needed characters exceeded