I am trying to upload a .skp file to a DB using a HTTP POST request. Since the request includes a query parameter, the body has to be of multipart/form-data type. The request also includes a header with some authorization info.
file = ‘test.skp’
url = ‘https://my_files_host’
auth_token = ‘my_authorization_token’
folder_id = ‘my_folder_id’
Since .skp is a non-standard MIME Type, the Content-Type value was previoulsy unkwown, and it was treated as application/octet-stream. However, checking this link, we see that now we can treat it as application/x-koan. Actually this can solve the question raised here.
I have tried three different solutions in Ruby code:
- Using REST Client:
headers = { Authorization: auth_token, params: { folderId: folder_id } } ## query params are taken out of the headers hash according to rest-client docs body = { filename: File.new(file, 'rb') } response = RestClient.post(url_auth, body, headers)
Here the response obtained is nil. The problem is the .skp IO stream is not being read correctly, probably it is not possible to upload .skp files with this solution. It does work with a standard MIME type file, like a .txt.
- Using multipart-post:
uri = URI.parse(url) File.open(file) do |skp| request = Net::HTTP::Post::Multipart.new(uri.path, { 'filename' => UploadIO.new(skp, 'application/x-koan', file), 'folderId' => folder_id}) ## Also tried in the line above with 'application/octet-stream' and MIME::Types.type_for(file). Does not work either request.add_field('Authorization', auth_token) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true response = http.request(request) end
Here I obtain a Bad Request response, with message: “The ‘folderId’ parameter is missing”. According to the doc, I am passing the parameter correctly. Maybe I am missing something.
- Using net/http directly, based on this solution:
BOUNDARY = "AaB03x" headers = { 'Authorization' => auth_token, 'Content-Type' => "multipart/form-data; boundary=#{BOUNDARY}" } params = { 'folderId' => folder_id } body = [] body << "--#{BOUNDARY}\r\n" body << "Content-Disposition: form-data; name=\"filename\"; filename=\"#{File.basename(file)}\"\r\n" body << "Content-Type: #{MIME::Types.type_for(file)}\r\n\r\n" body << File.read(file) body << "--#{BOUNDARY}\r\n" body << "Content-Disposition: form-data; name=\"folderId\"\r\n\r\n" body << params.to_json body << "\r\n\r\n--#{BOUNDARY}--\r\n" http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri.request_uri, headers) request.body = body.join response = http.request(request)
Here I obtain a Bad Request response as well, with the same message than the previous case. I have observed tha the IO stream of the .skp file is not read correctly again, so when the body is joint, the query parameter is missing.