Пытаюсь послать методом POST бинарный файл на сервер

SiMM

Новичок
Shurgenz, подслушиваешь заголовки (PHP FAQ: Самые основы. Просмотр обмена HTTP заголовками), которые передаются на сервер при реализации UPLOAD'а файла средствами браузера (PHP FAQ: Как делать UPLOAD файлов на сервер) и поступаешь в своём клиентском приложении аналогичным образом, посылая POST-запрос, сформированный так же, как это делает браузер.
После этого расслабляешься и больше не лохматишь бубушку и не морочишь людям голову.
 

Фанат

oncle terrible
Команда форума
Shurgenz, кстати, SiMM прав.
Твой компонент умеет посылать формы urlencoded/form-data?
 

Shurgenz

Guest
посылаю я так:
rq.Open "POST", "http://www.somesite.ru/myscript.php", 0

rq.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
rq.SetRequestHeader "Content-Length", CStr(Len("filename=" & sTemp & ".gz&filecontent=" & sHTTP))

-~{}~ 26.03.05 23:59:

rq.Send "filename=" & sTemp & ".gz&filecontent=" & sHTTP

-~{}~ 27.03.05 00:00:

в sHTTP бинарные данные, в sTemp - название файла

-~{}~ 27.03.05 00:08:

извините за задержку... клаву пивом залил... а потом по дурости сломал... пришлось бежать к знакомым-менять... такие дела
 

fixxxer

К.О.
Партнер клуба
насколько я вижу, возможностей сего компонента предостаточно для отправки multipart/form-data.
читай http://www.faqs.org/rfcs/rfc1867.html
понадобится еще реализовать base64, но это несложно - самому или найти готовый код.

а можешь сделать "наоборот" - слать из клиента raw data (проще всего имя файла в GET и контент в POST), а принимать каким-нить сишным cgi типа
PHP:
#include <stdio.h>
#include <sys/file.h>
#define P_ERROR(s) ( printf("Status: 500 Error\nContent-type: text/html\n\n%s",s),exit(1) )
int main()
{
  char *query_string = (char *)getenv("QUERY_STRING");
  char *s_content_length = (char *)getenv("CONTENT_LENGTH");
  char *s;
  FILE *out;
  unsigned long content_length;
  if (!query_string || !strlen(query_string) || !s_content_length || strchr(query_string, '/')) 
    P_ERROR("Invalid query");
  content_length = (unsigned long)atol(s_content_length);
  if (!content_length) P_ERROR("Invalid query");
  s = (char *)malloc(content_length);
  if (!s) P_ERROR("Memory allocation error");
  if(!fread(s, content_length, 1, stdin)) {
    free(s);
    P_ERROR("Could not recv POST data");
  }
  out = fopen(query_string, "w");
  if (!out) { free(s); P_ERROR("Cannot write to file"); }
  if (!flock(fileno(out), LOCK_EX)) {
    fwrite(s, content_length, 1, out);
    flock(fileno(out), LOCK_UN);
  }
  fclose(out);
  free(s);
  printf("Content-type:text/html\n\nUploaded OK");
  return 0;
}
(код не проверял, но он компилится =))
 

Shurgenz

Guest
ENCTYPE="multipart/form-data" не помогает.

а base64 ... это что? юникод?

-~{}~ 28.03.05 00:45:

УРА

Это функция, преобразовывающая бинарное содержимое на клиенте

Public Function URLEncode(sRawURL As String) As String
On Error GoTo Catch
Dim iLoop As Integer
Dim sRtn As String
Dim sTmp As String, sTmpH As String
Const sValidChars = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz:/._-$(){}~"


If Len(sRawURL) > 0 Then
' Loop through each char


For iLoop = 1 To Len(sRawURL)
sTmp = Mid(sRawURL, iLoop, 1)


If InStr(1, sValidChars, sTmp, vbBinaryCompare) = 0 Then
sTmpH = Hex(Asc(sTmp))
sTmp = AscB(sTmp) 'Hex(AscB(sTmp))

If sTmp = "0" Then
sTmp = "%u0000"
ElseIf sTmp = "92" Then
sTmp = "%u005C"
Else
If sTmpH = "20" Then
sTmp = "+"
ElseIf Len(sTmpH) = 1 Then
sTmp = "%0" & sTmpH
Else
sTmp = "%" & sTmpH
End If
End If
End If
sRtn = sRtn & sTmp
Next iLoop
URLEncode = sRtn
End If
Finally:
Exit Function
Catch:
URLEncode = ""
Resume Finally
End Function


Пришлось исходник слегка переколбасить, ну и принимать файл немного похитрее:

<?php
$handle = fopen ($filename, "w");
if (!fwrite($handle, preg_replace('#%u([0-9A-F]{4})#se','iconv("UTF-16BE","Windows-1251",pack("H4","$1"))',$filecontent))) {
print "Cannot write to file ($filename)";
exit;
};
fclose($handle);
?>
 

SiMM

Новичок
Это ж надо простую задачу умудриться решать через жо..., посылая инфы в два раза больше, чем нужно.
Base64 никакого отношения к Unicode не имеет.
 

Shurgenz

Guest
Автор оригинала: SiMM
Это ж надо простую задачу умудриться решать через жо..., посылая инфы в два раза больше, чем нужно.
Base64 никакого отношения к Unicode не имеет.
Во-первых, не в 2 раза. 3 символа у меня только посылаются в юникоде.
во-вторых, почему-то, base64 не разрулило ничего.

А так, хоть и криво, на Ваш взгляд, зато работает, чего я и пытался добиться

PHP:
Public Function URLEncode(sRawURL As String) As String
    On Error GoTo Catch
    Dim iLoop As Integer
    Dim sRtn As String
    Dim sTmp As String, sTmpH As String
    Const sValidChars = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz:/._-$(){}~"


    If Len(sRawURL) > 0 Then
        ' Loop through each char


        For iLoop = 1 To Len(sRawURL)
            sTmp = Mid(sRawURL, iLoop, 1)


            If InStr(1, sValidChars, sTmp, vbBinaryCompare) = 0 Then
                sTmpH = Hex(Asc(sTmp))
                sTmp = Asc(sTmp)
                
                If sTmp = "0" Then
                    sTmp = "%u0000"
                ElseIf sTmp = "92" Then
                    sTmp = "%u005C"
                ElseIf sTmp = "39" Then
                    sTmp = "%u0027"
                Else
                    If sTmpH = "20" Then
                        sTmp = "%00"
                    ElseIf Len(sTmpH) = 1 Then
                        sTmp = "%0" & sTmpH
                    Else
                        sTmp = "%" & sTmpH
                    End If
                End If
            End If
            sRtn = sRtn & sTmp
        Next iLoop
        URLEncode = sRtn
    End If
Finally:
    Exit Function
Catch:
    URLEncode = ""
    Resume Finally
End Function
 

fixxxer

К.О.
Партнер клуба
во-вторых, почему-то, base64 не разрулило ничего
Потому что надо читать указанный RFC. Или хотя бы взглянуть на то, как выглядит почтовое сообщение с аттачем.
 

Shurgenz

Guest
То ли я никого понять не могу, то ли меня... Попробую спросить по-другому: что нужно писать в POST, чтоб подавая на входе символы 8-битного диапазона (именно, с кодами 0-255), без искажения их получать на другом конце. Я, хоть и криво эту задачу решил. А есть ли способ проще?
 

fixxxer

К.О.
Партнер клуба
Да, и:
1) этот способ описан в RFC 1867 (в последний раз повторяю).
2) для этого способа в PHP предусмотрены специальные возможности: [m]features.file-upload[/m].
 

Shurgenz

Guest
я просил только пример показать, как POST написать, в RFC в основном про формы пишется... да с формой я в первую же очередь написал то что надо... только не годится с формой.

В том то и дел, что без формы надо. Клиент у меня в виндах написан, сидит на MSSQL. Задача - обмен через сайт... Только сайт невидимый. Там только скрипты по заливке данных в mysql, по безопасности скрипты, по формированию обменного файла. Никакого интерактива в HTML не требуется. За обмен с сайтом в приложении отвечает всего одна кнопка. Такие дела.

Смотрел я этот RFC. Там мне, к примеру, мало что понятно... В смысле, непонятно, как это применить.. Видел я такое:

Content-disposition: attachment; filename="file2.gif"
Content-type: image/gif
Content-Transfer-Encoding: binary

...contents of file2.gif...
--BbC04y--
--AaB03x--
Вроде бы о том, что надо... но сразу же вопрос... как это должно смотреться в типичном HTTP POST? Только его я и умею делать. На своей то стороне. Ну что там в ...contents of file2.gif...? В каком представлении? и что означают --BbC04y--
--AaB03x-- ... Беда.
 

Фанат

oncle terrible
Команда форума
В том то и дел, что без формы надо
ты POST эмулируешь без формы.
Хотя судя по всем твоим примерам ты GET используешь.
так непонятно совершенно - urlencoded форму у тебя не вызывает проблем эмулировать ,f просто другой enctype - уже не получается. неувязочка.

Впрочем, ты же уже сделал, как тебе надо? ну и ради бога. не хочешь в рфц разбираться - заставить-то тебя никто не может
 

SiMM

Новичок
> не хочешь в рфц разбираться - заставить-то тебя никто не может
Да и особо разбираться, собственно, необязательно

> я просил только пример показать, как POST написать
Ставь сниффер да делай по аналогии, если в RFC разбираться лень. Уж по Base64 инфу в гугле найти не суметь - это надо умудриться.
 
Сверху