Загрузить файлы на Google Диск с помощью ColdFusion

* НОВОЕ ОБНОВЛЕНО ДЛЯ ЛУЧШЕГО ВТОРОЙ ЧАСТИ - ТЕПЕРЬ ДОходит до «308 резюме неполное», хотя файл должен быть только одной загрузкой!

Я использую основу cfgoogle от Рэя Камдена. Но Google устарел код для загрузки документов. Новым стандартом является возобновляемая загрузка мультимедиа.

У меня эта часть работает (вплоть до «Инициирования возобновляемого запроса на загрузку») в указанном выше документе Google.

Страница вызова:

<cfset application.cfc.Google                   = createObject('component','#path_cf_cfc#Google') />
<cfset application.cfc.GoogleDocs               = createObject('component','#path_cf_cfc#GoogleDocs') />

<cfset gtoken = application.cfc.GoogleDocs.authenticate(emailaddress,password)>

<CFSET testdoc = "a\filepath\documentname.doc">
<CFSET FileType = "application/msword">
<CFSET FileTitle = "test_001">

<cfset temp = application.cfc.GoogleDocs.upload_auth("#Application.Map.DocStorage##tv.testdoc#",FileType,FileTitle)>  

<CFSET uploadpath = Listgetat(Listgetat(temp.header,ListContains(temp.header,"https://docs.google.com","#chr(10)#"),"#chr(10)#"),2," ") >  

<cfset temp2 = application.cfc.GoogleDocs.upload_file("#Application.Map.DocStorage##tv.testdoc#",FileType,FileTitle,uploadpath)>

Код работает до временной строки cfset включительно (получение уникального URI загрузки)

Вот код для upload_auth:

<cffunction name="upload_auth" access="public" returnType="any" hint="I get a uniqu URI from Google API." output="false">
<cfargument name="myFile" type="string" required="true" hint="filepath to upload.">
<cfargument name="myType" type="string" required="true" hint="application/msword"> 
<cfargument name="myTitle" type="string" required="true" hint="name of doc"> 

<cfset GoogleUrl = "https://docs.google.com/feeds/upload/create-session/default/private/full">
<cfset GoogleVersion = 3> 
<cfset FileSize = createObject("java","java.io.File").init(myFile).length()>

<cfhttp url="#GoogleUrl#" method="post" result="diditwork" resolveurl="no">
<cfhttpparam type="header" name="Authorization" value="GoogleLogin auth=#getAuth(variables.docservice)#">
<cfhttpparam type="header" name="GData-Version" value="#GoogleVersion#">
<cfhttpparam type="header" name="Content-Length" value="0">
<cfhttpparam type="header" name="X-Upload-Content-Type" value="#myType#">
<cfhttpparam type="header" name="X-Upload-Content-Length" value="#FileSize#">
<cfhttpparam type="header" name="Slug" value="#myTitle#">

</cfhttp>

<cfreturn diditwork>
</cffunction>

ОК - пока все хорошо. Но вот где он ломается:

Запуск upload_file возвращает «308 Resume Incomplete» (если это не 400!) от Google. Аааа!!

Вот файл upload_file -

<cffunction name="upload_file" access="public" returnType="any" hint="I upload the document." output="false">
<cfargument name="myFile" type="string" required="true" hint="filepath to upload.">
<cfargument name="myType" type="string" required="true" hint="like application/msword"> 
<cfargument name="myTitle" type="string" required="true" hint="name of doc"> 
<cfargument name="myAuthPath" type="string" required="true" hint="call auth"> 

<cfset FileSize = GetFileInfo(myFile).size >
<CFSET tv.tostartwithzero = FileSize - 1>

<CFFILE action="read" file="#myfile#" variable="FileText">

<cfhttp url="#myAuthPath#" method="put" result="diditwork" resolveurl="no" multipart="yes" charset="utf-8" >
<cfhttpparam type="header" name="Authorization" value="GoogleLogin auth=#getAuth(variables.docservice)#">
<cfhttpparam type="header" name="GData-Version" value="#variables.GoogleVersion#">
<cfhttpparam type="header" name="Content-Length" value="#FileSize#">
<cfhttpparam type="header" name="Content-Range" value="bytes 0-#tv.tostartwithzero#/#FileSize#">
<cfhttpparam type="header" name="Content-Type" value="#myType#">

<cfhttpparam type="body" value="#trim(FileText)#">

</cfhttp>

<cfreturn diditwork>
</cffunction>

Итак, вот оно, где я застрял. Я могу получить уникальный URI, но (может быть, потому что уже поздно) я не понимаю, что я делаю неправильно, иначе завершить загрузку файла.

Вся помощь приветствуется.


person Community    schedule 02.01.2013    source источник
comment
Я заметил, что в заголовке диапазона содержимого вы используете размер файла, считанный с диска, но в теле вы отправляете обрезку (FileText), что означает, что если файл содержит начальные или конечные пробелы, размер тела запроса будет меньше, чем размер, который вы хотите отправить. Вы можете попробовать использовать len(trim(FileText)) для вычисления диапазона и размера отправки в заголовках content-range и content-length?   -  person barnyr    schedule 03.01.2013
comment
Вы также можете попробовать сделать FileReadBinary и отправить его в теле запроса, если нет причины обрезать содержимое файла.   -  person barnyr    schedule 03.01.2013
comment
Вы решили это? Найдено следующее здесь. После получения тела запроса на возобновление сервер может по-прежнему не располагать полным диапазоном байтов, что потребует от клиента дальнейших действий (например, дополнительных запросов). В таких случаях серверу СЛЕДУЕТ возвращать код состояния 308 (Resume Incomplete), если он все еще готов продолжить операцию. По определению, ответ 308 (Resume Incomplete) указывает, что клиент может исправить текущую состояние ошибки при отправке байтов, которых нет на сервере   -  person Miguel-F    schedule 29.01.2013


Ответы (1)


Я настоятельно рекомендую использовать другой подход здесь. Есть две большие проблемы с тем путем, которым вы идете:

  • Похоже, код использует устаревший механизм аутентификации входа клиента и использует имя пользователя/пароль вместо OAuth.
  • Использование устаревшего API списка документов вместо нового Drive API.

Поскольку вы можете вызывать java, я бы предложил написать код загрузки на простом Java, а затем вызывать его со страниц CF по мере необходимости.

person Steve Bazyl    schedule 05.04.2013