project-mirai / mirai-api-http

Mirai HTTP API (console) plugin
GNU Affero General Public License v3.0
1.66k stars 343 forks source link

Failed posting `/file/upload` while receiving 200 OK #493

Closed ryuujo1573 closed 3 years ago

ryuujo1573 commented 3 years ago
resp_upload = requests.post(f"{base_url}/file/upload", headers={
    # 'Content-Type': 'multipart/form-data',
}, files={
    'sessionKey': session,   ###
    'type': 'group',
    'target': ________,
    'path': '/0_0.png',
    'file': ('0_0.png', open('0_0.png', 'rb')),
})

In this case, it showed: '{"code":3,"msg":"Session失效或不存在"}'. // Session deprecated or it does not exist Nonetheless, I succeeded in send messages (less than 2 chars only) with the same procedure as this case.

resp_upload = requests.post(f"{base_url}/file/upload", headers={
    # 'Content-Type': 'multipart/form-data',
    'sessionKey': session,   ###
}, files={
    'type': 'group',
    'target': 937066966,
    'path': '/0_0.png',
    'file': ('0_0.png', open('0_0.png', 'rb')),
})

and in this case, it showed: '{"code":400,"msg":"无效参数"}' // invalid argument

and and

resp_upload = requests.post(f"{base_url}/file/upload", headers={
    'Content-Type': 'multipart/form-data',  ###
    'sessionKey': session,
}, files={
    'type': 'group',
    'target': 937066966,
    'path': '/0_0.png',
    'file': ('0_0.png', open('0_0.png', 'rb')),
})

which told me '{"code":500,"msg":"Failed to parse multipart: Content-Type\'s boundary parameter is missing"}'

and and and

resp_upload = requests.post(f"{base_url}/file/upload", headers={
    'Content-Type': 'multipart/form-data',
    'boundary': '&',  ###
    'sessionKey': session,
}, files={
    'type': 'group',
    'target': 937066966,
    'path': '/0_0.png',
    'file': ('0_0.png', open('0_0.png', 'rb')),
})

well nothing changed.

I was bloody confused, any advice would be appreciated. tks.

ryoii commented 3 years ago

Which version of the plugin are you using? I can't reproduce your case with api tester.

I reviewed your code and this the third case you posted is right but it seems to fail because of a wrong multipart format. I am not familiar with python, I am not sure the correct way to send multipart request. Maybe, you could have a try to test the api with some tools with the version you are using

ryoii commented 3 years ago

I found some solutions that may help you. The most likely solution is to remove the Content-Type header. Your http client may not generate the ramdon boundary while setting the content type yourself.

If you have to add the request header yourself, Its format is probably like 'Content-Type': 'multipart/form-data; boundary=(random_string)'.

By the way, the parameter of path means the directory your upload. The filename will be read from the file automatically.

ryuujo1573 commented 3 years ago

Thanks for your hints Soon I figured out that I should watch the actual outposting data, and I found that its my fault to put all stuffs in files parameter, and I got a resp of better look which is like:

{
    "code": 0,
    "msg": "",
    "data": {
        "name": "0_0.png",
        "id": "/3b0d8bc9-913c-48e8-b650-0a8931a0f035",
        "path": "/0_0.png",
        "parent": {
            "name": "",
            "id": null,
            "path": "/",
            "parent": null,
            "contact": {
                "id": 10000000,
                "name": "_____name____",
                "permission": "MEMBER"
            },
            "isFile": false,
            "isDictionary": true,
            "isDirectory": true,
            "size": 0,
            "downloadInfo": null
        },
        "contact": {
            "id": 10000000,
            "name": "_____name____",
            "permission": "MEMBER"
        },
        "isFile": true,
        "isDictionary": false,
        "isDirectory": false,
        "size": 7109,
        "downloadInfo": null
    }
}

and with code (the proper version I think hmmm)

resp_upload = requests.post(f"{base_url}/file/upload", headers={
    # 'Content-Type': 'multipart/form-data',
    # 'boundary': '--------------------------756537252445992812314949',
    'sessionKey': session,
}, files={
    'file': open('0_0.png', 'rb'),
}, data={
    'type': 'group',
    'target': 937066966,
    'path': '',
})

and it worked! xdddd thank a lot for you earliest reply

ltiaw commented 2 years ago

用这种上传文件可以上传,但是返回的结果是 {"code":500,"msg":"Sending FileMessage is not in support"} consle报错: 2021-12-07 11:14:39 V/Bot.763370799: Group(51022656) <- [mirai:file:123dd.mp3,/321fd347-1599-41c1-a703-39837cc9aaf3,8898395,102] 2021-12-07 11:14:39 E/MAH Access: java.lang.IllegalArgumentException: Sending FileMessage is not in support java.lang.IllegalArgumentException: Sending FileMessage is not in support at net.mamoe.mirai.internal.contact.UtilKt.verifySendingValid$fail(util.kt:38) at net.mamoe.mirai.internal.contact.UtilKt.verifySendingValid(util.kt:43) at net.mamoe.mirai.internal.contact.UtilKt.verifySendingValid(util.kt:41) at net.mamoe.mirai.internal.contact.SendMessageHandlerKt.sendMessageImpl(SendMessageHandler.kt:351) at net.mamoe.mirai.internal.contact.SendMessageHandlerKt.sendMessage(SendMessageHandler.kt:330) at net.mamoe.mirai.internal.contact.GroupImpl.sendMessage(GroupImpl.kt:168) at net.mamoe.mirai.api.http.adapter.internal.action.FileKt.onUploadFile(file.kt:147) at net.mamoe.mirai.api.http.adapter.internal.action.FileKt$onUploadFile$1.invokeSuspend(file.kt) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.internal.ScopeCoroutine.afterResume(Scopes.kt:33) at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.kt:102) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106) at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)

上传语音用这种不行

ryoii commented 2 years ago

files和data分开,我看你的demo是全部放到files的