2015-04-28 2 views
1

Я занимаюсь разработкой web-сервера (Apache 2.4 в Linux) и пытается поддерживать загрузку файлов с клиентской стороны на сервер. Мне удалось получить файл на стороне сервера, но я получаю дополнительные заголовки в загруженном файле, который я хочу опустить. Например, я при загрузке example.txt, которые содержат:Загрузка файла на сервер Apache в C (без заголовков)

I'm the file content! 

В стороне сервера файл я получаю:

------WebKitFormBoundaryqbGGz0VOmz7CVPCF 
Content-Disposition: form-data; name="file"; filename="example.txt" 
Content-Type: application/octet-stream 
I'm the file content! 
------WebKitFormBoundaryqbGGz0VOmz7CVPCF-- 

Фактический файл с бинарным, так что вы должны точно определить содержание без дополнение данные.

Я использовал эти примеры: mod_upload и mod_csv.

Мой север сторона код:

apr_bucket_brigade* bb; 
apr_bucket* b; 
int status = 0; 
int end = 0; 
char* fname = 0; 
const char* buf; 
apr_size_t bytes; 
char buffer[512]; 
apr_file_t* tmpfile; 

char* tmpname = apr_pstrdup(r->pool, "/tmp/tmp-upload.XXXXXX") ; 

if (apr_file_mktemp(&tmpfile, tmpname, KEEPONCLOSE, r->pool) != APR_SUCCESS) { 
    ap_remove_input_filter(r->input_filters) ; 
} 

apr_pool_cleanup_register(r->pool, tmpfile, (void*)apr_file_close, apr_pool_cleanup_null) ; 
bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); 

do { 
    status = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES, APR_BLOCK_READ, BLOCKSIZE) ; 
    if (status == APR_SUCCESS) { 
     for (b = APR_BRIGADE_FIRST(bb) ; b != APR_BRIGADE_SENTINEL(bb) ; b = APR_BUCKET_NEXT(b)) { 
      if (APR_BUCKET_IS_EOS(b)) { 
       end = 1; 
       break; 
      } 
      else if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ) == APR_SUCCESS) { 
       apr_file_write(tmpfile, buf, &bytes); 
       char* x = apr_pstrndup(r->pool, buf, bytes); 
       if (fname) 
        fname = apr_pstrcat(r->pool, fname, x, NULL); 
       else 
        fname = x; 
      } 
      else { 
       ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Bucket read error") ; 
      } 
     } 
    } 
    else { 
     ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Brigade error") ; 
    } 
    apr_brigade_cleanup(bb); 
} while (!end && status == APR_SUCCESS); 
apr_brigade_destroy(bb); 

return OK; 

Любые идеи, как изменить код, чтобы избежать избыточных заголовков в содержании результата файла/любой другой путь (/) метод, чтобы получить файл на сервере?

Спасибо!

ответ

0

Итак ... моим решением было вручную удалить эти префикс & суффикс-заголовки. Это может помочь кому-то в будущем:

int getPrefixHeaderLength(const char* buf) { 
    int rows = 0; 
    int counter = 0; 
    char* ret = buf; 

    if (buf == NULL) 
     return 0; 

    while (*ret != 0 && rows < 4) { 
     if (*ret == '\n') 
      rows++; 

     ret++; 
     counter++; 
    } 

    return counter; 
} 

/* example buf: "... filename="example.txt" " */ 
void getFilename(const char* buf, char* filename) 
{ 
    char* pEnd = NULL; 
    char *pFilename = strstr(buf,"filename"); 
    pFilename += 10; 
    pEnd = strchr(pFilename,'"'); 
    snprintf(filename,pEnd-pFilename+1,"%s",pFilename); 
} 

apr_bucket_brigade* bb; 
apr_bucket* b; 
int status = 0; 
int end = 0; 
char* fname = 0; 
const char* buf; 
apr_size_t bytes; 
apr_size_t totalBytes = 0; 
char buffer[512]; 
apr_file_t* tmpfile; 
const char* ctype = apr_table_get(r->headers_in, "file-0") ; 
int prefixFlag = 1; 
int counter = 0; 
apr_off_t offsetIndex = 0; 
char filename[512]; 

char* tmpname = apr_pstrdup(r->pool, "/tmp/tmp-upload.XXXXXX") ; 

if (apr_file_mktemp(&tmpfile, tmpname, KEEPONCLOSE, r->pool) != APR_SUCCESS) { 
    ap_remove_input_filter(r->input_filters) ; 
} 

apr_pool_cleanup_register(r->pool, tmpfile, (void*)apr_file_close, apr_pool_cleanup_null) ; 

bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); 

do { 
    status = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES, APR_BLOCK_READ, BLOCKSIZE) ; 
    if (status == APR_SUCCESS) { 
     for (b = APR_BRIGADE_FIRST(bb) ; b != APR_BRIGADE_SENTINEL(bb) ; b = APR_BUCKET_NEXT(b)) { 
      if (APR_BUCKET_IS_EOS(b)) { 
       end = 1; 
       break; 
      } 
      else if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ) == APR_SUCCESS) { 
       int prefixHeaderLength = 0; 
       apr_size_t sizeToWrite; 

       if (prefixFlag) { 
        if (bytes == 1) { 
         continue; 
        } 

        prefixHeaderLength = getPrefixHeaderLength(buf); 
        prefixFlag = 0; 
        getFilename(buf,filename); 
        ap_rprintf(r, "\"filename\":\"%s\",",filename); 
       } 
       //ap_rprintf(r, "\"counter%d\":%d,",counter,bytes); 
       sizeToWrite = bytes - prefixHeaderLength; 
       apr_file_write(tmpfile, buf+prefixHeaderLength, &sizeToWrite); 
       //ap_rprintf(r, "\"write%d\":%d,",counter,sizeToWrite); 
       totalBytes += bytes; 
      } 
      else { 
       ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Bucket read error") ; 
      } 
     } 
    } 
    else { 
     ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Brigade error") ; 
    } 
    apr_brigade_cleanup(bb); 
    counter++; 
} while (!end && status == APR_SUCCESS); 

counter = 0; 

while (counter < 2) { 
    char c; 
    offsetIndex = -2L; 
    apr_file_seek(tmpfile,SEEK_CUR, &offsetIndex); 
    apr_file_getc(&c,tmpfile); 

    if (c == '\r') 
     counter++; 
} 

apr_file_trunc(tmpfile,offsetIndex); 
ap_rprintf(r, "\"size\":%d}",totalBytes); 

apr_brigade_destroy(bb); 
return OK; 
1

http://apache.webthing.com/mod_upload/mod_upload.c

Здесь

static void set_header(upload_ctx* ctx, const char* data) 

Эта функция добавления заголовков. Если вы не хотите заголовки, тогда не вызывайте эту функцию в этом файле.

+0

Я не использую mod_upload.c (я пробовал, но не получилось), я просто скопировать код оттуда (тот, который вы видите выше), поэтому я 'не вызывать set_header – ItayB

Смежные вопросы