Pergunta

Estou trabalhando em uma série de scripts Powershell para minha empresa usar para transferir dados de e para Box.com.A única coisa que não consigo descobrir é o upload de arquivos.A API Box requer uma operação POST multiparte para uploads, e vi algumas respostas aqui no SO indicando que devo ser capaz de fazer isso no Powershell (como Este).Mas não consigo fazê-lo funcionar.

Aqui está o código que tenho agora:

Function Post-File {
    Param(
            [Parameter(Mandatory=$True,Position=1)]
            [string]$SourcePath,
            [Parameter(Mandatory=$False,Position=2)]            
            [string]$FolderId = ############
    )

    #Variables for building URIs
    $baseUrl = "https://upload.box.com/api/2.0/files/content"

    #Set Authorization for API requests
    $headers = @{}
    $AccessToken = Refresh-Tokens #A reference to another function that definitely works
    $headers.Add("Authorization", "Bearer $AccessToken")

    #Set POST content
    $body = @{}
    $body.Add("filename",  [IO.File]::ReadAllBytes($SourcePath))
    $body.Add("parent_id", $FolderId)

    #Upload the file
    Invoke-RestMethod -Uri $baseUrl -Method Post -Headers $headers -ContentType "multipart/form-data" -Body $body
}

Aqui está a resposta que recebo:

{
 "type":"error",
 "status":400,
 "code":"invalid_request_parameters",
 "help_url":"http://developers.box.com/docs/#errors",
 "message":"Invalid input parameters in request",
 "request_id":"1764475572534bcddfe04b7"
}

Também tentei algumas outras permutações que não estão funcionando.Eu tentei usar o -InFile alternar em Invoke-RestMethod em vez de -Body.Eu também tentei usar Get-Content -Raw no lugar de [IO.File]::ReadAllBytes.Ambos retornam um erro mais genérico: The server encountered an internal error or misconfiguration and was unable to complete your request..

Tenho certeza de que isso tem algo a ver com o meu filename parâmetro não está correto, mas não sei como corrigi-lo.De acordo com API de caixa, aqui está como deve ficar em curl.Alguém pode me ajudar a traduzir isso corretamente para o Powershell?

https://upload.box.com/api/2.0/files/content \
-H "Authorization: Bearer ACCESS_TOKEN" \
-F filename=@FILE_NAME \
-F parent_id=PARENT_FOLDER_ID
Foi útil?

Solução

Há algumas coisas que tornam isso um pouco complicado no PowerShell:

  1. O filename parâmetro especifica o nome do arquivo, não o conteúdo.
  2. Um corpo de solicitação é necessário para especificar o nome e o destino do arquivo.
  3. Guloseimas do PowerShell -InFile e -Body argumentos como mutuamente exclusivos.
  4. O PowerShell não parece oferecer suporte nativo multipart/form-data POSTs, de acordo com o pergunta que você referiu.

Como o corpo da solicitação é necessário (1,2) - e, portanto, -InFile não pode ser usado (3) - acho que você pode precisar criar o seu próprio multipart/form-data corpo (4) que contém os metadados e o conteúdo do arquivo necessários. Esta postagem do blog descreve um método para fazer isso.O conteúdo é uma sequência curta (um tweet), mas o princípio é o mesmo.

Abaixo está um rastreamento do Fiddler de um upload que acabei de realizar usando o Box Windows SDK.Isso mostra como a solicitação deve ficar à medida que passa pela rede.O $BOUNDARY é uma string arbitrária e única - um GUID funciona muito bem.

POST https://upload.box.com/api/2.0/files/content HTTP/1.1
Authorization: Bearer $TOKEN
Content-Type: multipart/form-data; boundary="$BOUNDARY"
Host: upload.box.com
Content-Length: 2118
Accept-Encoding: gzip, deflate

--$BOUNDARY

Content-Disposition: form-data; name="file"; filename="$FILENAME"

<THE CONTENT OF $FILENAME>    

--$BOUNDARY

Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name="metadata"

{"parent":{"id":"$PARENT_FOLDER_ID"},"name":"$FILENAME"}

--$BOUNDARY--

Aqui está a resposta que recebi:

HTTP/1.1 201 Created
Date: Mon, 14 Apr 2014 12:52:33 GMT
Server: Apache
Cache-Control: no-cache, no-store
Content-Length: 364
Connection: close
Content-Type: application/json

{"total_count":1,"entries":[{"type":"file","id":"$ID","name":"$FILENAME", ... }]}

Outras dicas

Posso parecer idiota, mas o que acontece quando você faz isso?

$body.Add("filename",  $([IO.File]::ReadAllBytes($SourcePath)))
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top