2017-07-17 131 views
7

我目前正在嘗試使用nghttp2來構建多部分消息。信息應該如下所示。nghttp2多部分POST消息

enter image description here

我應該使用nghttp2_submit_request(here)功能,具有nva作爲我的HTTP/2報頭,並且爲nghttp2_data_provider *data_prd我的數據。但是,我仍然不明白我怎樣才能創建兩條消息(帶有兩個消息標題)。


更新:

是否有可能,我來形容我是覺得在我的源代碼?請看下面。在這裏,我使用nghttp2_data_provider打開一個音頻文件,並寫入緩衝區。

ssize_t data_prd_read_callback(
    nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length, 
    uint32_t *data_flags, nghttp2_data_source *source, void *user_data) 
{ 

    printf("[INFO] C ----------------------------> S (DATA post body), length:%zu\n", length); 

    int fd = source->fd; 
    ssize_t r; 
// writting my opened audio file into buffer 
    while ((r = read(fd, buf, length)) == -1 && errno == EINTR); 
    printf("stream_id:%d, nread:%zu\r\n", stream_id, r); 
    return nread; 
} 



void submit_postAudio(http2_session_data *session_data) { 
    int32_t stream_id; 
    http2_stream_data *stream_data = session_data->stream_data[STREAM_ID_REQUESTAUDIO]; 
    const char *uri = stream_data->uri; 
    const struct http_parser_url *u = stream_data->u; 
    char byLength = 0; 

    const nghttp2_nv hdrs[] = { 
    MAKE_NV(":method", "POST"), MAKE_NV_CS(":path", stream_data->path), 
    MAKE_NV(":scheme", "https"), MAKE_NV("accept", "*/*"),  
    MAKE_NV_CS("authorization", stream_data->access_token), 
    MAKE_NV("content-type", "multipart/form-data; boundary=abcdefg123") 
    }; 

    fprintf(stderr, "Request headers:\n"); 
    print_headers(stderr, hdrs, ARRLEN(hdrs)); 

    int fileDescriptor = open ("/my_audio.wmv", O_APPEND); // open my audio file 
    nghttp2_data_provider data_prd; 
    data_prd.source.fd = fileDescriptor // set the file descriptor 
    data_prd.source.ptr = NULL; 
    data_prd.read_callback = data_prd_read_callback; 

    stream_id = nghttp2_submit_request(session_data->session, NULL, hdrs, 
            ARRLEN(hdrs), &data_prd, stream_data); 
    if (stream_id < 0) { 
    errx(1, "Could not submit HTTP request: %s", nghttp2_strerror(stream_id)); 
    } 

    stream_data->stream_id = stream_id; 
} 

什麼困惑我是 1)如何添加頁眉(郵件標題更具體)的音頻。 2)如何在我的Json文件後追加它。

回答

0

多部分MIME頭通常定義是這樣的:

-----boundary_id 
name: value # header stuff here, ie. "name: value" per line. No spaces in name, all ASCII 
CRLF   # End of header is defined with an extra linefeed, AKA a "null line", see ref 1. 

content here, ends at next boundary id 

-----boundary_id 

Ref 1

如果內容是二進制的,你會usually encode it as base-64具有固定線的長度(你可以太發送二進制數據但是必須對諸如最終換行符等額外的空白空間採取預防措施)。報頭字段名通知,說明可以包括:

Content-Transfer-Encoding: Base64 

(對於二進制數據時使用的值「二進制」代替)。

邊界ID必須足夠獨特,不會冒任何其他內容的風險。它在主標題中定義時不使用雙破折號,但是您需要在它作爲分隔符的任何位置添加這樣的雙破折號。

因此,在這種情況下,整個消息將是這個樣子:

name1: value1 
name2: value2 
name3: value3 
x-comment: "as required by the specs (ignore this line)" 
content-type: multipart/form-data; boundary: my_unique_boundary_id 

--my_unique_boundary_id 
Content-Disposition: form-data; name="metadata" 
Content-Type: application/json; charset=UTF-08 

{JSON data here} 

--my_unique_boundary_id 
Content-Disposition: form-data; name="audio" 
Content-Type: application/octet-stream 
Content-Transfer-Encoding: Base64 
x-comment: "binary audio encoded as base-64 follows next" 

UklGRuKlAABXQVZFZm10ICgAAAABAAEARKwAAIhYAQACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
AAAAc2NvdLQBAAAAAAAAVGhlIFJoeXRobSBNYWNoaW5lICAgICAgICAgICAgICAgICAgICAgICAg 
IFRSTTEAICA6MDAAAAAAAAAvADAwMDAwMDAwMDAwMAAAALkBTQABAAAAJQAAAAAAAAAAAAAAAAAA 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABKYXNvbiBE 
b25uZWxseSAoYWthIGRqIHB1enpsZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg 
ICAgIDAwQwAAAAAAADEyMTMwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
... etc. 

--my_unique_boundary_id 
+0

的頭從身體中的最後一個MIME分出一部分需要空行。 – Alex

+0

@Alex ups,我在刪除CRLF表示時意外刪除了 – K3N

+0

感謝您的回答。從'ssize_t data_prd_read_callback'( nghttp2_session * session,int32_t stream_id,uint8_t * buf,size_t length, uint32_t * data_flags,nghttp2_data_source * source,void * user_data)',我只有一個緩衝區('uint8_t *')來寫我的有效載荷。你是否建議只用這種格式編寫char(使用正確的間距和換行符),然後跟隨音頻文件? – wrek