如何将文件上传到box.com

时间:2014-04-22 16:29:12

标签: ruby-on-rails

我正在将文件上传到box.com,但我被困在那里。我使用Net :: HTTP,我需要关于这个库的帮助。

我与box.com互动的主要代码是

module BoxApi
  class FileOperation < Base
    attr_reader :upload_path

    def initialize
      super
      @upload_path = "https://upload.box.com/api/2.0/files/content"
    end

#here filder_id args denote folder inside upload file and file args hold the content of file which are uploaded by file_field

    def upload(folder_id, file)
       boundary = "AaB03x"
       body = []
       body << "--#{boundary}\r\n"
       body << "Content-Disposition: form-data; name='filename'; filename=#{file.original_filename}\r\n"
       body << "Content-Type: text/plain\r\n\r\n"
       body << file
       body << "--#{boundary}\r\n"
       body << "Content-Disposition: form-data; name='parent_id'"
       body << "\r\n"
       body << folder_id
       body << "\r\n--#{boundary}--\r\n"

      https_post(URI.parse("#{upload_path}"), body, boundary)
      # `curl "Authorization: Bearer MlaNbyAefUWrawZEqGkDKvq9foCmQ0lL" -F filename=@./public/404.html -F parent_id='#{folder_id}' #{upload_path}`
    rescue => ex
      p "Exception caught (1) ==> #{ex}"
    end

    private
    def https_post(uri, body, boundary)
      http = https_setting(uri)
      request = Net::HTTP::Post.new(uri.request_uri)
      # request.body = JSON.parse(body)
      request.body = body.join
      request["Content-Type"] = "multipart/form-data, boundary=#{boundary}"
      request["Authorization"] = "Bearer #{box_token.token}"
      http.request(request)
    rescue => ex
      p "Exception caught (2) ==> #{ex}"
    end

    def https_setting(uri)
      http = Net::HTTP.new(uri.host, uri.port)
      http.use_ssl = true
      http.verify_mode = OpenSSL::SSL::VERIFY_NONE  
      http
    end
  end
end

1 个答案:

答案 0 :(得分:0)

这是我的Powershell代码,它使用System.Net.HttpWebRequest

param(
    $FileRequestID ,
    $FileToUpload 
)

$BoxDomain = "yourenterprise.ent.box.com"

$URL = "https://$($BoxDomain)/app-api/file-request-web/public/file-request?urlId=$($FileRequestID)"

$resultsRaw = Invoke-WebRequest -Uri $URL -Method GET -UseBasicParsing

$resultsJson = ConvertFrom-Json $resultsRaw.Content
$boxFileRequestId = $resultsJson.id
$boxFolderId = $resultsJson.folder.id

$fileInfo = [System.IO.FileInfo]$FileToUpload
$ProcessStartDateTime = Get-Date
$ProgressName = "$($fileInfo.Name) Upload Progress"

$requestContent = "{`"fileRequestURL`":`"$($FileRequestID)`",`"formVersionId`":`"303881722`",`"values`":{`"element-0`":{`"type`":`"files`",`"data`":[{`"local_path`":`"$($fileInfo.Name)`",`"size`":$($fileInfo.Length)}]},`"folder`":{`"type`":`"folder`",`"id`":`"$($boxFolderId)`"}}}"
$UploadFormResponse = Invoke-WebRequest -Uri "https://$($BoxDomain)/app-api/file-request-web/public/form-response" -Method POST -ContentType "application/json;charset=UTF-8" -Body $requestContent -UseBasicParsing

$UploadFormResponseJson = ConvertFrom-Json $UploadFormResponse.Content

$requestContent = "{`"name`":`"$($fileInfo.Name)`",`"parent`":{`"id`":`"$($boxFolderId)`"},`"size`":$($fileInfo.Length)}" 
$OptionsResponse = Invoke-WebRequest -Uri "https://$($BoxDomain)/api/2.1/files/content" -Method OPTIONS -Body $requestContent -Headers @{ Authorization = "Bearer $($UploadFormResponseJson.uploadToken)";} -UseBasicParsing

$OptionsResponseJson = ConvertFrom-Json $OptionsResponse.Content

$UploadURL = $OptionsResponseJson.upload_url

$boundary = "---------------------------" +[System.DateTime]::Now.Ticks.ToString("x");
$boundarybytes = [System.Text.Encoding]::ASCII.GetBytes("`r`n--" + $boundary + "`r`n");
$wr = [System.Net.HttpWebRequest]([System.Net.WebRequest]::Create($UploadURL));
$wr.ContentType = "multipart/form-data; boundary=" + $boundary;
$wr.Method = "POST";
$wr.KeepAlive = $true;
$wr.PreAuthenticate = $true
$wr.Headers.Add("Authorization", "Bearer $($UploadFormResponseJson.uploadToken)")
$wr.AllowWriteStreamBuffering = $false
$wr.SendChunked = $true
$rs = $wr.GetRequestStream();

#Write attributes
$rs.Write($boundarybytes, 0, $boundarybytes.Length);
$formAttributes = "Content-Disposition: form-data; name=`"attributes`"`r`n`r`n{`"name`":`"$($fileInfo.Name)`",`"parent`":{`"id`":`"$($boxFolderId)`"},`"content_modified_at`":`"$($fileInfo.LastWriteTimeUtc.ToString("yyyy-MM-ddTHH:mm:ssZ"))`"}"

$formAttributesBytes = [System.Text.Encoding]::UTF8.GetBytes($formAttributes)
$rs.Write($formAttributesBytes, 0, $formAttributesBytes.Length)

#Write File
$rs.Write($boundarybytes, 0, $boundarybytes.Length);
$formFile = "Content-Disposition: form-data; name=`"file`"; filename=`"$($fileInfo.Name)`"`r`nContent-Type: application/octet-stream`r`n`r`n"
$formFileBytes = [System.Text.Encoding]::UTF8.GetBytes($formFile)
$rs.Write($formFileBytes, 0, $formFileBytes.Length)

[System.IO.FileStream]$fileStream = [System.IO.File]::Open($fileInfo.FullName, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite)
$buffer = [System.Byte[]]::new(1048576)
$bytesRead = 0;
$totalBytesRead = 0
$totalBytesToRead = $fileInfo.Length
while (($bytesRead = $fileStream.Read($buffer, 0, $buffer.Length)) -ne 0) {
    $rs.Write($buffer, 0, $bytesRead);
    $rs.Flush()
    $totalBytesRead += $bytesRead
    $SecondsElapsed = ((Get-Date) - $ProcessStartDateTime).TotalSeconds
    $SecondsRemaining = ($SecondsElapsed / ($totalBytesRead / $totalBytesToRead)) - $SecondsElapsed
    Write-Progress -Activity $ProgressName -PercentComplete (($totalBytesRead/$($totalBytesToRead)) * 100) -CurrentOperation "$("{0:N2}" -f ((($totalBytesRead/$($totalBytesToRead)) * 100),2))% Complete" -SecondsRemaining $SecondsRemaining
}
$fileStream.Close();
$trailerBytes = [System.Text.Encoding]::ASCII.GetBytes("`r`n--" + $boundary + "`r`n");
$rs.Write($trailerBytes, 0, $trailerBytes.Length);
$rs.Close();

#Done writing File

$wresp = $wr.GetResponse();
$wresp.StatusCode
$stream2 = $wresp.GetResponseStream();
$reader2 = New-Object -TypeName System.IO.StreamReader -ArgumentList $stream2
$response = ConvertFrom-Json ($reader2.ReadToEnd())
#$response