• [视频点播] 使用PHP SDK,web端的华为云视频点播接入,加密视频播放
    背景:由于公司近期有视频点播的需求,且要求视频不能被盗链和下载,因此看了华为云视频服务中的文档后,觉得适合我们的需求。于是我看了所有的文档与相应的文档,包括java的sdk和php的sdk代码,经过一天的摸索,终于在前端页面看到了我要播放的视频。总体来说大致是这样几个步骤:1、全局设置选项里面设置转码模板,记得打开加密和视频格式HLS,其他随便选择。2、视频点播控制台上传视频,具体步骤参考相关官方文档。3、在视频管理选项里面点击转码,打开查看详情,此时请记住HLS的播放地址结尾为m3u8。4、全局设置-》安全设置-》HLS加密,填入一个自己服务器能访问的地址,功能是调用华为云点播接口,接口返回的数据为json格式,可以用json_decode转为数组,然后用base64.decode数组里面的明文值,这个值用echo输出,return没试过。5、视频管理-》选择视频的详情-》查看网页演示代码,将代码复制黏贴到自己的网站目录下。6、在网页的html中的js代码player.src后面地址改写成这样http://{domain}/asset/{asset_id}/play_video/{token}/index.m3u8,其中token为32位,前期跑demo的时候可以随便写一个。7、网页打开浏览既可以观看。总结:1、token只是用于客户端与自己服务器之间的合法性访问。2、华为云文档上说的秘钥说了一大堆,结果所有的工作都在web页面引入华为指定的js时已经完成了,无需关注。3、在设计上,秘钥接口不要频繁请求,官方文档里推荐把秘钥存入缓存,可以判断缓存里时候有秘钥,有的话直接返回,没有的就请求接口存入缓存;另外,秘钥的核对是华为云自动进行的,在播放视频时引入的华为云js会自动核验。因此,可以这样设计代码,以mvc为例:1、播放器页面的控制器生成token存入缓存中,并把token渲染在页面上的其他地方,播放器的播放地址此次的url中不包括token的字符串。2、播放器播放按钮点击,将在页面中的token上传到自己的服务器检验是否有效,如验证成功,将token拼接至url里,动态覆盖播放器的播放地址进行播放请求。3、代码见下一篇。
  • [技术干货] InstanceCacheChecker: |instance cache not match
    早期的服务中心版本存在一个bug。当实例下线的时候,revision信息没有变化,SDK感知不到实例下线。 SDK为了检测这个BUG,做了一个功能,会定时(缺省是24小时)检测服务中心的实例列表和本地列表是否一致,不一致会发送告警,用户可以手工触发重新刷新SDK缓存。 (在CSE界面操作)2018-12-19 09:11:00.970|[Service Center Task]|ERROR|[InstanceCacheChecker.java:119]|instance cache not match. appId=AppGallerySearchService, microservice=AppGallerySearchService:AppGalleryMicroContentService.local cache: [{"instanceId":"0fa1021ff24911e888a800163e0b0521","serviceId":"0f95a43bf24911e888a800163e0b0521","endpoints":["rest://10.1.130.140:8087"],"hostName":"ncn-hispace-govportal-1-130-140","status":"UP","properties":{},"healthCheck":{"mode":"push","port":0,"interval":30,"times":3,"ttl":120},"environment":null,"stage":null,"dataCenterInfo":{"name":"AppMarket","region":"North-China","availableZone":"JiuXianQiao"}},{"instanceId":"78aa5835035f11e9a9c100163e0b085a","serviceId":"789d2f4f035f11e9a9c100163e0b085a","endpoints":["rest://10.1.130.140:18080"],"hostName":"ncn-hispace-govportal-1-130-140","status":"UP","properties":{},"healthCheck":{"mode":"push","port":0,"interval":30,"times":3,"ttl":120},"environment":null,"stage":null,"dataCenterInfo":{"name":"AppMarket","region":"North-China","availableZone":"RunZe"}}]remote cache: [{"instanceId":"78aa5835035f11e9a9c100163e0b085a","serviceId":"789d2f4f035f11e9a9c100163e0b085a","endpoints":["rest://10.1.130.140:18080"],"hostName":"ncn-hispace-govportal-1-130-140","status":"UP","properties":{},"healthCheck":{"mode":"push","port":0,"interval":30,"times":3,"ttl":120},"environment":null,"stage":null,"dataCenterInfo":{"name":"AppMarket","region":"North-China","availableZone":"RunZe"}}]这个功能可以帮助用户发现一些潜在问题,但是不是根本解决方案。 如果用户自己部署了服务中心,建议及时升级到最新版本, SDK也做好定期持续升级,避免老版本的BUG对业务产生影响。 
  • [技术干货] esdk-obs-java 扩展包
    本SDK是对华为OBS原生SDK(com.huawei.storage:esdk-obs-java)包装,在其基础上,提供断点上传、断点下载、回调、进度速率监控等特性。因此,本SDK不是原生SDK的替代,而是对原生SDK的补充。开发者应首先参考原生SDK的用户手册,在熟悉原生SDK的基础上再使用本SDK。下载链接:release一、功能1. 断点上传将整个上传任务转化为分段上传,每上传完一分段,在断点文件中记录完成分段上传结果,等所有分段上传成功后,合并所有分段。如果上传过程被中断,再次上传时,会读取断点文件中记录的分段结果,对于已经上传成功的分段不用再次上传。2.  断点下载将整个下载任务转化为分段(范围)下载,每个分段被成功的写入本地文件中后,在断点文件中记录完成分段结果,所有分段写入成功,即完成下载。如果下载过程被中断,再次下载时,会读取断点文件中记录的分段结果,对于已经成功的分段不用再次下载。3.  过程信息返回(进度,速率)在上传、下载操作中,对待上传的流/下载的流使用 ReadBytesMonitorInputStream 包装,其监控读取流的字节总数,并生成某一时刻的快照信息(包括总字节数、当前已读取字节数、当前时间、上一快照已读取字节数、上一快照时间等信息), 可以通过快照信息计算出进度、速率、是否完成等。二、日志配置参考原生SDK日志配置方式,如果要打印本SDK日志,配置logger name为"com.obs.extension"即可。注:当前SDK打印的日志级别为debug。<Logger name="com.obs.extension" level="debug" additivity="false">     <AppenderRef ref="NorthInterfaceLogAppender" /> </Logger>三、初始化该SDK提供了统一的对象操作门面,IObjectOperateClient。 要初始化 IObjectOperateClient ,需要传入原生SDK的obsClient实例,obsClient实例的初始化参考原生SDK手册。示例:IObjectOperateClient objectOperateClient = ObjectOperateClientImpl.newInstance(obsClient);四、代码示例1.  文件上传分段上传文件,支持断点续传和速率监控,IParallelUploadFuture 可以获取整个文件的速率信息,也可以获取每个分段上传的速率信息。//分段下载下载,开启断点续传和速率监控,关闭完整性校验 public void downloadFileWithProcessing() throws InterruptedException { String downloadFilePath = ""; String objectKey = ""; DownloadFileRequest request = new DownloadFileRequest(bucketName, objectKey); request.setDownloadFile(downloadFilePath); request.setEnableCheckpoint(true); request.setPartSize(5242880L); IParallelDownloadFuture downloadFuture = objectOperateClient.downloadFileAsyncWithProgress(request, false, printCallback); printProcessingInfo(downloadFuture.aggregationProcessing()); objectOperateClient.shutdown(); }2.  文件下载分段下载桶中对象到本地,支持断点续传、速率监控特性。//分段下载下载,开启断点续传和速率监控,关闭完整性校验 public void downloadFileWithProcessing() throws InterruptedException { String downloadFilePath = ""; String objectKey = ""; DownloadFileRequest request = new DownloadFileRequest(bucketName, objectKey); request.setDownloadFile(downloadFilePath); request.setEnableCheckpoint(true); request.setPartSize(5242880L); IParallelDownloadFuture downloadFuture = objectOperateClient.downloadFileAsyncWithProgress(request, false, printCallback); printProcessingInfo(downloadFuture.aggregationProcessing()); objectOperateClient.shutdown(); }3. printProcessingInfo() 方法public void printProcessingInfo(IProcessing processingInfo) throws InterruptedException { while (!processingInfo.isComplete()){ System.out.println("是否支持速率信息:" + processingInfo.isSupportProgress()); if(processingInfo.isSupportProgress()) { System.out.println("总字节数: " + processingInfo.getTotalBytes()); System.out.println("进度: " + processingInfo.getProgress()); } System.out.println("已传输: " + processingInfo.getTransferedBytes()); System.out.println("速率: " +processingInfo.perSecondRate() + " bytes/s"); System.out.println("-------------"); TimeUnit.MILLISECONDS.sleep(1000); } if (processingInfo.isComplete()) { System.out.println("是否支持速率信息:" + processingInfo.isSupportProgress()); if(processingInfo.isSupportProgress()) { System.out.println("总字节数: " + processingInfo.getTotalBytes()); System.out.println("进度: " + processingInfo.getProgress()); } System.out.println("已传输: " + processingInfo.getTransferedBytes()); System.out.println("速率: " +processingInfo.perSecondRate() + " bytes/s"); System.out.println("-------------"); } }
  • [技术干货] CSEJavaSDK连sc报错 404:Not Found, &quot;error_msg&quot;:&quot;API not exist or not published in the environment&quot;
    某些时候微服务注册到华为云CSE的时候,日志里面会打印错误内容2018-11-05 17:17:04.208  WARN 12692 --- [ntloop-thread-0] o.a.s.s.c.h.ServiceRegistryClientImpl    : get response for org.apache.servicecomb.serviceregistry.api.response.GetSchemasResponse failed, 404:Not Found, {"error_msg":"API not exist or not published in the environment","error_code":"APIGW.0101","request_id":"284c5c8b68ceed2411cbe958df208149"}这是由于microservice.yaml文件里面配置的连接服务中心、配置中心等的APIGateway地址还是旧域名https://cse.cn-north-1.myhwclouds.com,改成新的地址https://cse.cn-north-1.myhuaweicloud.com:443 就可以解决问题了。 PS:旧域名的APIGateway已经不更新了,并且预计以后会停止工作。推荐大家根据CSE或ServiceStage的CSE-SDK工具下载页面上发布的地址更新自己的配置
  • [技术干货] 使用CSE SDK在TCP、SSL握手过程中netty打印的日志如何关闭
    对于一些异常协议报文测试, CSE SDK 会打印大量的netty异常日志,比如:----TCP握手失败2018-09-03 14:13:31,843 [WARN ] [transport-vert.x-eventloop-thread-27][io.netty.util.internal.logging.Slf4JLogger.warn(Slf4JLogger.java:151)] An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.java.io.IOException: Connection reset by peerat sun.nio.ch.FileDispatcherImpl.read0(Native Method)at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)at sun.nio.ch.IOUtil.read(IOUtil.java:192)at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380)at io.netty.buffer.PooledUnsafeDirectByteBuf.setBytes(PooledUnsafeDirectByteBuf.java:288)at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1108)at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:345)at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:148)at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645)at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)at java.lang.Thread.run(Thread.java:748)----SSL握手失败[2018-09-20 20:13:33,209/CST][transport-vert.x-eventloop-thread-4][WARN]An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception. io.netty.util.internal.logging.Slf4JLogger.warn(Slf4JLogger.java:151)io.netty.handler.codec.DecoderException: io.netty.handler.ssl.NotSslRecordException: not an SSL/TLS record: 474554202f20485454502f312e310d0a486f73743a203139322e3136382e302e3230343a383038320d0a436f6e6e656374696f6e3a206b6565702d616c6976650d0a43616368652d436f6e74726f6c3a206d61782d6167653d300d0a557067726164652d496e7365637572652d52657175657374733a20310d0a557365722d4167656e743a204d6f7a696c6c612f352e30202857696e646f7773204e542031302e303b20574f57363429204170706c65576at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:459)at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434)at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)at io.netty.channel.AbstractChannelHandlerC可以通过:log4j.logger.io.netty.channel.DefaultChannelPipeline=ERROR,paas,stdout来关闭。 注意修改下后面的pass, stdout为自己的logger。关闭后,对于底层协议(TCP、SSL)可能没有任何错误信息。 会给定位带来麻烦。需要注意下。 新版本会做适当的优化,即即使给这个日志关闭,也打印少量的信息。
  • [技术干货] SDK如何设置超时时间?
    默认情况下SDK设置的超时时间是30秒,如果处理时间超过这个时间,则会打印超时日志,请求失败:2018-08-28 12:01:18,401 [ERROR] [transport-vert.x-eventloop-thread-14] [org.apache.servicecomb.transport.rest.client.http.RestClientInvocation.lambda$invoke$0(RestClientInvocation.java:97)] Failed to send request to /177.66.54.95:8443.java.util.concurrent.TimeoutException: The timeout period of 30000ms has been exceeded while executing PUT /rest/cbc/cbccustomerorgservice/v1/em/apply/apply-status for host 177.66.54.95当业务出现超时,并且是30s缺省设置的时候,应该尝试优化性能或者处理流程,已让系统更好的服务。比如设计流程,将超时操作作为后台任务运行,调用是立即返回的,然后通过状态查询接口来查询任务处理状态。不建议业务的接口处理时间超过10s以上,这样会设计到一系列性能问题。 当然,是开发测试阶段,可以通过下面的配置修改超时时间:servicecomb.rest.client.connection.idleTimeoutInSeconds: 30cse.request.timeout: 30000请求超时时间需要比IdelTimeout大一点
  • [视频点播] VOD SDK能做什么?
    简介媒体云点播服务软件开发工具包(VOD SDK,Video on Demand Software Development Kit)是对VOD服务提供的REST API进行的封装,以简化用户的开发工作。用户直接调用VOD SDK提供的接口函数即可实现使用VOD服务业务能力的目的。概述VOD SDK是对点播服务接口请求的封装,提供的接口包括创建媒资、确认媒资上传、媒资更新、媒资发布、媒资发布取消、查询媒资信息、修改媒资属性、删除媒资、媒资处理、CDN预热、创建媒资分类、修改媒资分类、删除媒资分类、查询分类及其子分类。请大家在使用SDK前务必先去查看点播服务的产品文档,了解相关接口的功能、参数、规则和使用方法。SDK工作流程除了点播服务SDK之外,用户还需集成其他SDK(如OBS SDK)。在创建媒资过程中用户与这几个SDK之间的配合如下:
  • [技术干货] VOD SDK过程中遇到异常问题的解决办法
    1、连接超时出现此类异常原因一般是服务地址(Endpoint)错误或网络不通导致无法连接服务,此时请检查服务地址、网络状况和代理设置。2、错误处理在使用Java SDK时,当服务端或者SDK端出错时,SDK会返回相应的异常信息。这些异常信息中会包含具体的错误信息,例如错误码(Error Code)和错误消息(Error Message)。  "Error Code"是错误码,可以查看错误码定义,找到对应的错误描述,找出对应的错误类型。 "Error Message"是错误信息,可以快速的帮助定位问题,找出错误原因并解决。 如果您需要对SDK的错误进行处理,可以参考如下示例编写代码:/** 业务流程:* 1、首先需要导入点播sdk包VodSDK.jar* 2、设置点播服务配置项,包括点播服务节点地址、AK、SK和ProjectId等,用于连接点播服务和进行授权等。* 3、构造媒资发布请求参数,没有填必填字段* 4、发送媒资发布请求。* 5、返回处理信息。*/import com.google.gson.Gson;import com.huawei.vod.client.ClientConfig;import com.huawei.vod.client.VodClient;import com.huawei.vod.client.VodConfig;import com.huawei.vod.model.Asset.PublishAssetReq;import com.huawei.vod.model.Asset.PublishAssetRsp;//设置点播服务配置项构造方法VodConfig vodConfig = new VodConfig();//设置用户项目编号ProjectId,查看项目ID参考 "查看项目ID"章节vodConfig.setProjectId("projectId");//设置点播服务节点地址,如点播服务的Endpoint当前为“vod.cn-north-1.myhuaweicloud.com”vodConfig.setEndPoint("endPoint");//设置SK,SK的获取方法请参考"创建访问密钥" 章节vodConfig.setAk("ak");vodConfig.setSk("sk");//点播服务构造方法,在没有配置代理的情况下使用该构造方法VodClient vodClient = new VodClient(vodConfig);//设置媒资发布请求参数PublishAssetReq req = new PublishAssetReq();//媒资id是必填的,但在这里没有填写媒资id//String[] assets = {"asset1", " asset2"};//设置媒资发布的媒资IDreq.setAsset_id(req);//发送媒资发布请求PublishAssetRsp rsp = vodClient.publishAssets(req);//如果返回错误if(BaseResponse.FAIL == rsp.getStatus()){    // 这里可以添加您自己的错误处理逻辑    // 例如,打印具体的错误信息    System.out.println("ErrorCode ="+ rsp.getErrorCode());    System.out.println("ErrorMsg ="+ rsp.getErrorMsg());}//如果返回成功else{    //返回处理结果    System.out.println(new Gson().toJson(rsp));} 
  • [技术干货] 使用nodejs实现head携带验证信息方式实现上传和下载简单技术分享
    为公司有通知文件管理和归档的需求,所以购买了一个华为云OBS服务,使用自开发接口来进行通知文件的上传下载,由于通知文件有短时高并发访问的特点,决定使用nodejs来实现,毕竟node在通讯和IO上有他独特的优势。开发过程中遇到了一些小坑,但是在华为云服务技术人员的支持下,完成了核心的功能上传和下载,这里简单的分享下。华为文档在官网上都可以查询到,需要根据文档来进行开发的,部分文档说明不明确的地方可能会造成开发人员的困惑,我这里会对这些进行简单的说明。华为云OBS有标准的nodejs-SDK,可以进行下载使用,只是该SDK不是很适用于我们的项目,因为我们小文件居多,也有自己的业务组件,所以没有采用SDK的方式进行实现,而使用了更轻量级的head携带信息进行请求的方式来进行实现。查阅head方式调用api的文档。核心内容就是head的Authorization的签名生成,这里直接举例子进行签名的生成,下面将分别从实例上介绍上传和下载的功能实现。至于秘钥文件的获取和部分前台操作相信大部分运维人员会搞定,这里就不做详细说明了。 场景:桶下有一个文件需要下载,桶命:buk1,文件名:test.txt,下载到本地项目目录./buk1/test/ 路径下第一步,构造请求的URL,这里注意。需要把文件的key拼接在云服务桶的endpoint后。比如,从前台获取到的桶的endpoint是http://桶名.obs.cn-south-1.myhwclouds.com,你要下载文件的key是/test.txt,这个时候你的完整的请求url就是http://桶名.obs.cn-south-1.myhwclouds.com/test.txt;第二步,构造Authorization参数,这里的组成请参考官网文档,值得注意的是,不要随意颠倒拼接的顺序,要严格按照官网的顺序进行拼接,拼接的时候注意以下几点:1.标准时间,这里注意的是,使用的是格林威治的标准时间,不需要进行时区的转换,node重获取这个时间和时间字符串的方法如下var gmdate = new Date();var utcdate = gmdate.toUTCString();2.请求方法,下载的请求方法为GET,node中直接定义var httpMethod = ‘GET’ 即可;3.SK:SK全名SecretAccessKeyID,作为加密的秘钥,这个可以从前台获取4.AK:AK全名AccessKeyid,作为一个标识,放入Authorization头,后面会说明5.CanonicalizedHeaders 和 CanonicalizedResource,按照文档进行配置,下载这里有时候需要加入一个Content-Type字符串避免签名验证失败,例如txt类型的文件的Content-Type就是text/plain准备好以上的变量后就是开始计算Signature了,根据华为OBS文档,这里直接展示拼接的字符串在node中的代码var beforestr = ‘GET’+ "\n" + "\n" + "text/plain\n" + 时间(utcdate变量) + "\n" + "/桶名/test.txt";这个字符串注意几点,除了最后,每个字符串拼接需要拼接一个‘\n’,直接使用字符串即可,不用考虑转义。关于text/plain就是txt文件的Content-Type,有时候必须加入这个参数后才不会出现403签名错误,最后的字符串参照文档即可,即/桶名/key名,具体各种文件的Content-Type可以查阅附件(从官方标准SDK中剥出来的)ContentType.rar接下来就是对这个字符串进行加密,。加密的过程很标准,这里直接给出代码,如下       var signaturestr =crypto.createHmac("sha1",秘钥(SecretAccessKeyID)).update(utf8.encode(beforestr)).digest().toString("base64");       到此获取完最复杂的签名后就是构造请求头部,这里比较简单,直接贴出代码做简单说明        var headarr = {                "Date": utcdate,  //这里的时候就是注意使用上方的签名中的时间字符串,避免在new一个新的,会造成时间不一致导致签名失败                "Host": "桶名.obs.cn-south-1.myhwclouds.com",//照抄,注意这里不要在尾部添加文件key                "Authorization": "OBS AK(AccessKeyid):" + signaturestr,   //注意空格和:                "Content-Type": " text/plain " //这里尤其要注意和上方加密的字符串保持一致,意思就是字符串中有,这里必须有,否则将导致签名错误        }; 至此,需要准备的变量都完成了,准备进行API请求,我使用的是node的request模块,这里比较简单,直接贴出代码。注意保存路径必须存在,否则会出错,相关验证请自行根据应用场景添加var options = {        url: http://桶名.obs.cn-south-1.myhwclouds.com/test.txt        headers: headarr    };httprequest(options).pipe(fs.createWriteStream(‘./buk1/test/test.txt’)).on("close", function (err) {        if (err) {            console.log(err);            //错误操作        }      //成功操作      });关于上传:      有了下载的经验,实现上传就简单的多了。直接贴出代码(代码片段,比如模块引入等,不全请注意自行补全).      场景:把代码目录下的test.txt上传到:桶名/test.txt 的key中      但是有个注意点需要特别注意,就是自定义CanonicalizedHeaders 和 CanonicalizedResource的时候,必须要按照文档的顺序,从上至下添加,不能违反文档的顺序,截图如下,并且要注意各个API允许的CanonicalizedHeaders 和 CanonicalizedResource是不一样的,要遵循文档结合应用场景进行设计。  var crypto = require('crypto');var utf8 = require('utf8');var fs = require('fs');var httprequest = require(‘request’)fs.readFile('./test.txt', function (err, data) {        if (err) {            console.log(err);        }        console.log('----------data---------------')        console.log(data);        console.log('-----------------------------');         var datalength = data.length;          var url = 'http://桶名. obs.cn-south-1.myhwclouds.com/test.txt';         console.log('url---->' + url);        var gmdate = new Date();        var utcdate = gmdate.toUTCString();        var httpMethod = "PUT";  //注意,上传使用的是PUT方式        var beforestr = httpMethod + "\n" + "\n" + "text/plain\n" + utcdate + "\n" + 'x-obs-acl:public-read\nx-obs-storage-class:STANDARD\n' + "/桶名/test.txt"; //注意x-obs-*的顺序        console.log('------------para-------------');        console.log(beforestr);        console.log('-----------------------------');        var SecretAccessKeyID = "你的SK";         var signaturestr = crypto.createHmac("sha1", SecretAccessKeyID).update(utf8.encode(beforestr)).digest().toString("base64");        console.log('sing------------->' + signaturestr);        var headarr = {            "Date": utcdate,            "User-Agent": "curl/7.15.5",            "Host": "obs-e06d.obs.cn-south-1.myhwclouds.com",            "x-obs-acl": "public-read",    //注意x-obs-*的顺序和上方字符串一致            "x-obs-storage-class": "STANDARD", //注意x-obs-*的顺序和上方字符串一致            "Authorization": "OBS 你的AK:" + signaturestr,  //注意空格和:            "Content-Type": "text/plain",         //和上方字符串保持一致            "Content-Length": datalength       //长度不可省略        };        console.log('------------head-------------');        console.log(head);        console.log('-----------------------------');             var options = {            url:url,            headers: headarr,            body: data        };        httprequest.put(options, function (error, response, body) {            if (!error && response.statusCode == 200) {                //可以使用response获取返回的header,里面有部分OBS返回参数            } else {                //错误处理        });    })     至此,node通过head签名方式实现文件上传和下载就实现了。这里为了展示过程,没有进行任何代码封装,比较直观,方便看到具体过程。如有遇到问题或者更好的建议,欢迎各位大神指出,共同进步!谢谢!
  • [问题求助] SDK客户端接口调用抛出statusCode 400, reasonPhrase Bad Request, response content-type null is not supported
    transport-vert.x-eventloop-thread-30] [org.apache.servicecomb.loadbalance.LoadbalanceHandler$4.lambda$null$0(LoadbalanceHandler.java:278)] service CONSUMER rest CSBProdOfferingService.OfferingQueryProduct.queryBatchProduct, call error, msg is InvocationException: code=490;msg=CommonExceptionData [message=method POST, path /product/product-offering/v2/products/detail/, statusCode 400, reasonPhrase Bad Request, response content-type null is not supported], server is rest://177.66.15.110:8443?sslEnabled=true&urlPrefix=/ 原因:这个错误是因为provider返回400错误码。provider在接口定义的时候,API没声明400错误码,客户端无法解析,打印了异常。 可以通过查询provider日志进一步查询详细原因。
  • [问题求助] SDK开发启动报错Can not find any instances from service center due to previous errors. service=default/CseMonito...
    Can not find any instances from service center due to previous errors. service=default/CseMonitoring/latest 这个错误是由于服务启动的时候,尝试连接监控服务上报服务运行数据(metrics),由于线下开发没有部署这个服务,所以会打印这个日志。 监控服务的地址是自动发现的,如果连接失败,会重试。 因此刚启动的时候,可能频繁打印日志,这个重试如果几次不成功,会降低频率,后面2分钟才会打印一次。
  • 对象存储有php的sdk么
    有php的么
  • [技术干货] 用户使用OBS Java SDK报错&quot;UnknowHostException&quot;的解决方法
    [color=rgb(255,255,255)]编辑词条 【问题现象】 使用OBS Java SDK在Linux机器上使用“obs.myhwclouds.com”域名调用上传对象接口,报错"UnknowHostException"。 【分析过程】1.在运行环境上可正常ping通obs.myhwclouds.com,并且使用dig命令也能正常解析obs.myhwclouds.com,排除网络原因。 2.分析OBS Java SDK,所用的HttpClient框架底层是通过JDK标准库进行域名解析的,该标准库不会存在BUG,因此怀疑是运行环境的问题。 3.查询JDK标准库域名解析算法的相关资料,发现JDK标准库会读取运行环境上的/etc/resolv.conf文件,以获取DNS配置从而解析出IP,如果JVM进程对该文件没有读权限,可能导致"UnknowHostException"异常。 4.排查运行环境发现运行JVM进程的用户确实没有读/etc/resolv.conf文件的权限,修改权限后,问题解决。 【经验总结】报错的表象和根因看起来差得比较远,要深入问题本质才能分析出来。
  • 关于U-vMOS SDK集成
    请问有没有知道U-vMOS SDK集成Android的对应下载包的下载链接呢?或者这个SDK本身是收费的还是免费的呢?
  • PHP实现obs上传,是否需要obs的上传sdk
    PHP实现obs上传,是否需要obs的上传sdk
总条数:873 到第
上滑加载中