Subscribe for automatic updates: RSS icon RSS

Login icon Sign in for full access | Help icon Help
Advanced search

Pages: [1]
  Reply  |  Print  
Author Topic: Unable to upload file to Genero server - com.HTTPServiceRequest  (Read 19769 times)
Jan S.
Posts: 9


« on: August 26, 2014, 01:08:12 pm »

Hi,

I am trying to upload a file from Android client to Genero server using HTTP.
The multipart content of the HTTP request contains the only one single part with jpg image. There is no other body or file part.

My HTTP POST request looks like:

POST http://172.16.6.27:8090/upload HTTP/1.1
Host: 172.16.6.142:8888
User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.0.4; sdk Build/MR1)
Accept-Encoding: gzip, deflate
Connection: keep-alive
Accept: */*
Content-Type: multipart/form-data; boundary=----------------------------2a708b2baf25414eb7f47c63975a07b2
Content-Length: 22141

------------------------------2a708b2baf25414eb7f47c63975a07b2
Content-Disposition: form-data; name="IMG_20140529_103509.jpg"; filename="IMG_20140529_103509.jpg"

... data ...
------------------------------2a708b2baf25414eb7f47c63975a07b2--


Server 4gl code:

Code
  1. IMPORT com
  2. IMPORT xml
  3.  
  4. MAIN
  5.  DEFINE req        com.HTTPServiceRequest
  6.  DEFINE url        STRING
  7.  DEFINE method     STRING
  8.  DEFINE doc        xml.DomDocument
  9.  DEFINE type       STRING
  10.  DEFINE ind        INTEGER
  11.  DEFINE p          com.HTTPPart
  12.  DEFINE resp       STRING
  13.  DEFINE i          INTEGER
  14.  
  15.  DISPLAY "START"
  16.  CALL com.WebServiceEngine.Start()
  17.  
  18.  LET req = com.WebServiceEngine.getHTTPServiceRequest(-1)
  19.  LET url = req.getURL()
  20.  DISPLAY url
  21.  IF url IS NULL  THEN
  22.    DISPLAY "Failed: url should not be null"
  23.    EXIT PROGRAM (-1)    
  24.  END IF
  25.  
  26.  LET method = req.getMethod()
  27.  DISPLAY "method: ", method
  28.  IF method IS NULL OR method != "POST" THEN
  29.    DISPLAY "Failed: method should be POST"
  30.  END IF
  31.  
  32.  # Check multipart type
  33.  LET type = req.getRequestMultipartType()
  34.  DISPLAY "type: ", type
  35.  IF type IS NULL THEN
  36.    DISPLAY "Failed: expected multipart in request"
  37.  END IF
  38.  
  39.  # Process additional parts
  40.  LET resp = "count: ", req.getRequestPartCount()
  41.  DISPLAY resp
  42.  
  43.  FOR ind = 1 TO req.getRequestPartCount()
  44.    LET p = req.getRequestPart(ind)
  45.    IF p.getAttachment() IS NOT NULL THEN
  46.      LET resp = resp, " att: ", p.getAttachment()
  47.      DISPLAY "Attached file at :",p.getAttachment()
  48.    ELSE
  49.      LET resp = resp, " content: ", p.getContentAsString()
  50.      DISPLAY "Attached part is :",p.getContentAsString()
  51.    END IF
  52.  END FOR
  53.  
  54.  CALL req.sendTextResponse(200, "", resp)
  55.  
  56. END MAIN

But in the Genero I'm still getting request part count = 0.
Am I missing something?

Thanks

Jan



* POST_file_upload_request.txt (22.1 KB - downloaded 872 times.)
Frank G.
Four Js
Posts: 48


« Reply #1 on: August 26, 2014, 04:19:12 pm »

Hi,

  when you have only one part, it is considered as the main part and must be handled with the method req.readDataRequest().

Something like following :

  DEFINE b BYTE
  # Check multipart
  ...
  LOCATE b IN MEMORY
  CALL srv.readDataRequest(b)
  ...
  b.writeFile("myfile.jpg")


And all other parts will then be available via the getRequestPart() and getRequestPartCount().

Frank.
Jan S.
Posts: 9


« Reply #2 on: August 26, 2014, 04:58:02 pm »

Thanks for your reply.

However, now for the same requests, program on method call req.readDataRequest(b) is throwing these exceptions:

FORMS statement error number -15549.
HTTP runtime exception : Unexpected end of multipart protocol.

FORMS statement error number -15549.
HTTP runtime exception : Mulitpart protocol error 1.

Jan
Frank G.
Four Js
Posts: 48


« Reply #3 on: August 26, 2014, 06:36:08 pm »

Hi,

  I reproduced the issue and filed a new bug #GWS-442 : Reading a 'form-data' multipart response where first part contains a Content-Disposition header does not work.

 Sorry for the inconvenience

Frank
Frank G.
Four Js
Posts: 48


« Reply #4 on: August 27, 2014, 10:04:36 am »

Hi,

  As workaround, you can add a main part of type text in your HTML formular (maybe as hidden), and send as second part the file.
See attached sample.

Hope it helps
Frank


* workaround.zip (1.02 KB - downloaded 855 times.)
Jan S.
Posts: 9


« Reply #5 on: August 27, 2014, 01:58:19 pm »

Hi,

request posted from your html form is processed correctly.
But when I'm posting similar request with "hack" part from my Android client I'm getting another error, still on calling req.readDataRequest(b):

FORMS statement error number -15549.
HTTP runtime exception : No valid header on HTTP request..

Headers seem to be OK, if I get them by the req.getRequestHeaderValue() method and display to console before reading data part.

The request is attached.

Jan

* POST_file_upload_with_hack_request.zip (5.23 KB - downloaded 869 times.)
Frank G.
Four Js
Posts: 48


« Reply #6 on: August 27, 2014, 03:20:25 pm »

I did not reproduce with the workaround.zip test case on Android. I'm a bit confused, you say that you get an error on readDataRequest(), but this method is not called in my workaround test case.  Can you please clarify ?

Notice that I used Chrome as browser on Android, do you have another browser or a dedicated client app ?

Thanks
Jan S.
Posts: 9


« Reply #7 on: September 01, 2014, 09:50:35 am »

Hi,

sorry for your confusion. I tried various modifications. In your workaround case program fails on readTextRequest() with the same error message "HTTP runtime exception : No valid header on HTTP request..".

I'm sending request from my own native Android test app using Ion library (https://github.com/koush/ion) for networking.

my test upload method:

Code
  1.    public void uploadFile(String url, String filePath){
  2.        File file = new File(filePath);
  3.        Log.d(LOG_TAG, "exist: " + file.exists());
  4.  
  5.        Future<Response<String>> uploading;
  6.        Response<String> response = null;
  7.        try {
  8.            uploading = Ion.with(this)
  9.                    .load("POST", url)
  10.                    .setTimeout(3000)
  11.                    .setHeader("Connection", "Keep-Alive")
  12.                    .setMultipartParameter("hack", "")
  13.                    .setMultipartFile(file.getName(), file)
  14.                    .asString()
  15.                    .withResponse();
  16.            response = uploading.get();
  17.            if (response != null){
  18.                Log.d(LOG_TAG, "result: " + response.getResult());
  19.            } else {
  20.                Log.d(LOG_TAG, "response null");
  21.            }
  22.        } catch (Exception e) {
  23.            Toast.makeText(this, "error: " + e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
  24.        }
  25.    }

Jen



Frank G.
Four Js
Posts: 48


« Reply #8 on: September 04, 2014, 05:48:14 pm »

Hi,

  Sorry but I'm not able to reproduce. I did a dedicated android app using the Ion library and your code sample, but I'm still able to communicate with the FGL server.

  Could you maybe retry and set FGLWSDEBUG=3 before starting the fglrun server.

Thanks,
Frank
Jan S.
Posts: 9


« Reply #9 on: September 05, 2014, 09:16:29 am »

Hi,

I set FGLWSDEBUG=3 according to your advice.

output:


WS-DEBUG (Receive)
POST /upload HTTP/1.1
WS-DEBUG END


WS-DEBUG (Receive)
Host: chsrv07.vera.local:8090
User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.4.2; sdk Build/KK)
Accept-Encoding: gzip, deflate
Accept: */*
Connection: Keep-Alive
Content-Type: multipart/form-data; boundary=----------------------------8ae7246c4b534bc8bbabd1440aa66de2
Content-Length: 26011

WS-DEBUG END

http://chsrv07.vera.local:8090/upload
method: POST
type: form-data

WS-DEBUG (Receive)
------------------------------8ae7246c4b534bc8bbabd1440aa66de2\r\nContent-Disposition: form-data; name="hack"\r\n\r\n
WS-DEBUG END


WS-DEBUG (Receive)
\r\n
WS-DEBUG END


WS-DEBUG (Receive)
------------------------------8ae7246c4b534bc8bbabd1440aa66de2\r\nContent-Disposition: form-data; name="IMG_20140905_024752.jpg"; filename="IMG_20140905_024752.jpg"\r\n\r\n
WS-DEBUG END


WS-DEBUG (IO ERROR)
Class: HTTPHeader::readMultipart()
Msg: No valid header on HTTP request.
Code: 0
WS-DEBUG END


WS-DEBUG (HTTP ERROR)
Class: HTTPMultipartParser
Msg: No valid header on HTTP request.
WS-DEBUG END

Program stopped at 'MultipartServer.4gl', line number 45.
FORMS statement error number -15549.
HTTP runtime exception : No valid header on HTTP request..



Jan
Jan S.
Posts: 9


« Reply #10 on: September 05, 2014, 12:49:46 pm »

Hi,

until now I has been testing upload only with a program running in standalone mode. It's little strange that it works with various clients except Ion. Now I tried to deploy the MultipartServer program on the GAS. Through the GAS upload is working now even with a client using Ion library!

Thanks for your support Frank.

Jan
Pages: [1]
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines