编辑:我想我已经弄清楚如何处理二进制数据部分了。在代码中仔细检查它,但我很确定我做对了。现在我在尝试按照 Vimeo API documentation 中的描述完成上传时遇到了一个新错误
编辑 2:向 OAuthService 添加了 .debug() 并更新了输出。
原始问题:我正在尝试使用 Vimeo API (Streaming Method) 将视频上传到 Vimeo。我正在使用 scribe 授权我的应用程序,获取我的访问 token 并准备上传视频。我只是不知道 Vimeo API 文档在这个 PUT 的 HTTP 请求示例中说“您的文件的二进制数据”时该怎么做:
PUT http://1.2.3.4:8080/upload?ticket_id=abcdef124567890 HTTP/1.1
Host: 1.2.3.4:8080
Content-Length: 339108
Content-Type: video/mp4
.... binary data of your file here ....
我可以很好地获得票证和标题。只是,我该怎么做才能插入我的文件的二进制数据?
注意事项:
这是我的 put 代码(记住,我使用的是 scribe )
// Setup File (line 52)
File testUp = new File("C:/Users/Kent/Desktop/test.mp4");
String contentLength = Long.toString(testUp.length());
System.out.println("The content length is: " + contentLength);
byte[] fileBytes = ByteStreams.toByteArray(new FileInputStream(testUp));
// Upload file (line 58)
request = new OAuthRequest(Verb.PUT, endpoint);
request.addHeader("Content-Length", contentLength);
request.addHeader("Content-Type", "video/mp4");
request.addPayload(fileBytes);
response = signSendAndPrint(service, accessToken, request, "Upload PUT: " + endpoint);
// Check response code is valid (line 65)
if (response.getCode() != 200) {
System.out.println("The response was not 200! It was: " + response.getCode());
return;
}
// Verify the upload (line 71)
request = new OAuthRequest(Verb.PUT, endpoint);
request.addHeader("Content-Length", "0");
request.addHeader("Content-Range", "bytes */*");
response = signSendAndPrint(service, accessToken, request, "Verify Upload PUT: " + endpoint);
// Check response code is valid (line 77)
if (response.getCode() != 308) {
System.out.println("The response was not 308! It was: " + response.getCode());
return;
}
// Complete Upload (line 83)
request = new OAuthRequest(Verb.PUT, endpoint);
request.addQuerystringParameter("method", "vimeo.videos.upload.complete");
Response completeResponse = signSendAndPrint(service, accessToken, request, "complete"); // This is line 86, it's the second to top level of my code that breaks the process.
//Set video info (line 88)
setVimeoVideoInfo(completeResponse, service, accessToken, vimeoAPIURL);
}
/**
* Signs the request on the service, prints information on the request, sends the request, prints
* information on the response and returns the response
*
* @param service
* @param accessToken
* @param request
* @param description
* @return
*/
private static Response signSendAndPrint(OAuthService service, Token accessToken, OAuthRequest request, String description) {
service.signRequest(accessToken, request);
printRequest(request, description + " Request");
Response response = request.send(); //This is line 105. It's the top level of my code that breaks the process
printResponse(response, description + " Response");
return response;
}
signSendAndPrint(OAuthService service, Token accessToken, OAuthRequest request, String description) 方法和 OAuthService.debug() 的输出:
Upload PUT: http://174.129.155.54:8080/upload?ticket_id=a64ed67b4aefdc35d18aec6cfa0b7c5e Request
Headers: {Authorization=OAuth oauth_signature="MTPIVFfGVUQn4QswNV6av4CjzJw%3D", oauth_version="1.0", oauth_nonce="-606493399", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="MY_CONSUMER_KEY", oauth_token="MY_OAUTH_TOKEN", oauth_timestamp="1332428103", Content-Length=15125120, Content-Type=video/mp4}
Verb: PUT
Complete URL: http://174.129.155.54:8080/upload?ticket_id=a64ed67b4aefdc35d18aec6cfa0b7c5e
Upload PUT: http://174.129.155.54:8080/upload?ticket_id=a64ed67b4aefdc35d18aec6cfa0b7c5e Response
Code: 200
Headers: {null=HTTP/1.1 200 OK, Content-Length=0, Connection=close, Content-Type=text/plain, Server=Vimeo/1.0}
Body:
signing request: http://174.129.155.54:8080/upload?ticket_id=a64ed67b4aefdc35d18aec6cfa0b7c5e
setting token to: Token[87bddf1382ac9f423d4b7c4166bdf0b2 , fdae7a033c7e1c932abce533627d6045124e8593]
generating signature...
base string is: PUT&http%3A%2F%2F174.129.155.54%3A8080%2Fupload&oauth_consumer_key%3DMY_CONSUMER_KEY%26oauth_nonce%3D1585934110%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1332428110%26oauth_token%3DMY_OAUTH_TOKEN%26oauth_version%3D1.0%26ticket_id%3Da64ed67b4aefdc35d18aec6cfa0b7c5e
signature is: bhWu7IX9JKEEn/ULcpJECEuwqOc=
appended additional OAuth parameters: { oauth_signature -> bhWu7IX9JKEEn/ULcpJECEuwqOc= , oauth_version -> 1.0 , oauth_nonce -> 1585934110 , oauth_signature_method -> HMAC-SHA1 , oauth_consumer_key -> MY_CONSUMER_KEY, oauth_token -> MY_OAUTH_TOKEN, oauth_timestamp -> 1332428110 }
using Http Header signature
Verify Upload PUT: http://174.129.155.54:8080/upload?ticket_id=a64ed67b4aefdc35d18aec6cfa0b7c5e Request
Headers: {Authorization=OAuth oauth_signature="bhWu7IX9JKEEn%2FULcpJECEuwqOc%3D", oauth_version="1.0", oauth_nonce="1585934110", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="MY_CONSUMER_KEY", oauth_token="MY_OAUTH_TOKEN", oauth_timestamp="1332428110", Content-Length=0, Content-Range=bytes */*} *///Note, this is not part of the output, I just added */// so the rest of it doesn't appear commented out.
Verb: PUT
Complete URL: http://174.129.155.54:8080/upload?ticket_id=a64ed67b4aefdc35d18aec6cfa0b7c5e
Verify Upload PUT: http://174.129.155.54:8080/upload?ticket_id=a64ed67b4aefdc35d18aec6cfa0b7c5e Response
Code: 308
Headers: {null=HTTP/1.1 308 Resume Incomplete, Range=bytes=0-15125119, Content-Length=0, Connection=close, Content-Type=text/plain, Server=Vimeo/1.0}
Body:
signing request: http://174.129.155.54:8080/upload?ticket_id=a64ed67b4aefdc35d18aec6cfa0b7c5e&method=vimeo.videos.upload.complete
setting token to: Token[87bddf1382ac9f423d4b7c4166bdf0b2 , fdae7a033c7e1c932abce533627d6045124e8593]
generating signature...
base string is: PUT&http%3A%2F%2F174.129.155.54%3A8080%2Fupload&method%3Dvimeo.videos.upload.complete%26oauth_consumer_key%3DMY_CONSUMER_KEY%26oauth_nonce%3D3111236130%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1332428110%26oauth_token%3DMY_OAUTH_TOKEN%26oauth_version%3D1.0%26ticket_id%3Da64ed67b4aefdc35d18aec6cfa0b7c5e
signature is: vXlQ6OUKms8eHan+wEBO2HXBn/M=
appended additional OAuth parameters: { oauth_signature -> vXlQ6OUKms8eHan+wEBO2HXBn/M= , oauth_version -> 1.0 , oauth_nonce -> 3111236130 , oauth_signature_method -> HMAC-SHA1 , oauth_consumer_key -> MY_CONSUMER_KEY, oauth_token -> MY_OAUTH_TOKEN, oauth_timestamp -> 1332428110 }
using Http Header signature
complete Request
Headers: {Authorization=OAuth oauth_signature="vXlQ6OUKms8eHan%2BwEBO2HXBn%2FM%3D", oauth_version="1.0", oauth_nonce="3111236130", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="MY_CONSUMER_KEY", oauth_token="MY_OAUTH_TOKEN", oauth_timestamp="1332428110"}
Verb: PUT
Complete URL: http://174.129.155.54:8080/upload?ticket_id=a64ed67b4aefdc35d18aec6cfa0b7c5e&method=vimeo.videos.upload.complete
Exception in thread "main" org.scribe.exceptions.OAuthException: Problems while creating connection.
at org.scribe.model.Request.send(Request.java:70)
at org.scribe.model.OAuthRequest.send(OAuthRequest.java:12)
at autouploadermodel.VimeoTest.signSendAndPrint(VimeoTest.java:105)
at autouploadermodel.VimeoTest.main(VimeoTest.java:86)
Caused by: java.net.SocketException: Unexpected end of file from server
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:723)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:589)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:720)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:589)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1319)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:468)
at org.scribe.model.Response.<init>(Response.java:28)
at org.scribe.model.Request.doSend(Request.java:110)
at org.scribe.model.Request.send(Request.java:62)
... 3 more
Java Result: 1
最佳答案
完成上传时还需要附加另外两个参数。 Vimeo API documentation说你需要 vimeo.videos.upload.complete 的三个参数:文件名、oauth_token 和 ticket_id。 scribe 会为您处理 oauth_token。
此外,您必须调用原始端点,而不是请求票证时获得的端点。
关于java - HTTP PUT 在 Java 中上传文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9773705/
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信
我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A
我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只