2017-07-17 30 views
7

Şu anda çok gruplu bir ileti oluşturmak için nghttp2 kullanmaya çalışıyorum. Mesaj, aşağıdaki gibi strcuture olmalıdır.nghttp2 multipart POST iletisi

enter image description here

benim verileri için yaptığım HTTP/2 başlık olarak nva ve nghttp2_data_provider *data_prd ile nghttp2_submit_request(here) işlevini kullanmalısınız. Bununla birlikte, iki mesajı (iki mesaj başlığına sahip) tam olarak nasıl oluşturabileceğimi hala anlamıyorum.


Güncelleme:

beni benim kaynak kodunda düşünmek ne olduğunu tarif etmek mümkün müdür? Lütfen aşağıya bakın. Burada bir ses dosyasını açmak ve arabelleğe yazmak için nghttp2_data_provider kullanıyorum. Beni karıştı Ne

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; 
} 

olduğunu 1) nasıl ses kafayla (daha spesifik olmak için bir mesaj başlığı) eklerim. 2) Json dosyamdan sonra nasıl ekleyebilirim?

cevap

0

bir çok parçalı mim başlığı genellikle böyle tanımlanır:

-----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

içeriği sabit hat uzunluğu ile usually encode it as base-64 (eğer çok ikili veri gönderebilir ediyorum ikili ise ancak son satır beslemesi gibi ekstra beyaz alanlara ilişkin önlemler almak zorundadırlar). Bu belirten bir başlık alanı adı dahil edilebilir:

Content-Transfer-Encoding: Base64 

(ikili veri kullanım değeri "ikili" yerine).

Sınır kimliği, başka hiçbir içeriğin parçası olma riskini taşımayacak kadar benzersiz olmalıdır. Ana başlıkta tanımlandığında çift çizgi kullanmaz, ancak ayırıcı olarak hareket ettiği her yerde bu çift kesiklerle eklemeniz gerekir. Geçen MIME bölümünde vücuttan başlığını ayırmak için gerekli

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

Boş çizgi:

Yani bu durumda tüm ileti böyle bir şey olmazdı. – Alex

+0

@Alex ups, Bir CRLF gösterimini kaldırırken yanlışlıkla silindim – K3N

+0

Cevabınız için teşekkürler. Ssize_t data_prd_read_callback ( nghttp2_session * oturumundan, int32_t stream_id, uint8_t * buf, size_t uzunluğu, uint32_t * data_flags, nghttp2_data_source * source, void * user_data) ', sadece bir arabamı (' uint8_t * ') yazmak için için yük. Bu biçimde (doğru aralık ve yeni satır ile) char yazmayı ve sonra ses dosyasını takip etmeyi mi öneriyorsunuz? – wrek