Положить Файл На Сервер

Omh

Lotus team
04.07.2007
2 210
1
#1
Товарищи, добрый день!

Возникла проблема, взываю к помощи.

Есть, значит, лотусная база, предназначенная для работы через броузер. Короче, вебная база.

Есть некий процесс (электронная подпись), который сейчас работает так:
1. открывается форма с Java апплетом
2. апплету в параметрах подаётся URL на файл, который надо подписать (вида http://SERVER/PATH.nsf/0/UNID/$file/FILENAME.gif)
3. после трастинга апплет всё это дело скачивает в TEMP директорию локального компа (попутно с java классами)
4. апплет модифицирует исходный файл

В результате у нас есть файл лежащий в локальной TEMP папке.

Вопрос: как мне этот файл забрать обратно на сервер, приложить к документу и т.д.
У апплета есть параметр, куда cслать POST мессыдж с контетном файла, после того, как он успешно был модифицирован апплетом.
Параметр тоже подаётся в виде URL'a

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

Заранее спасибо за идеи!
 

VladSh

начинающий
Lotus team
11.12.2009
1 262
6
#2
Не понял 2 вещи.
1. В процессе подписания нам нужно получить саму подпись, грубо говоря, хэш некоторых данных. Для чего нам обратно вкладывать файл?
2. Для чего извлекать файл, если его (если это файл) можно из Java получить по url, тут же подписать, и записать подпись куда следует?
 

Kee_Keekkenen

Well-known member
05.09.2006
639
4
#3
а приаттачить (аплоад) в какой-нибудь документ через апплет можно ?
 

ToxaRat

Чёрный маг
Lotus team
06.11.2007
3 231
18
#5
подумать только, я эту задачу недавно поставил криптопровайдеру :)

поставь скрытый аплоад, где будет путь к твоему модифицированному файлу
и после нажатия кнопочки "подписать/проверить" всё это дело сабмитится
 

Omh

Lotus team
04.07.2007
2 210
1
#6
Прошу прощения за молчание на выходных: пароль дома не запомнен в форум, а скидывать пароль не хотелось.
Ну и да: пятница вечер не самое лучшее время для создания темы :)

VladSh
>В процессе подписания нам нужно получить саму подпись, грубо говоря, хэш некоторых данных.
Тут речь идёт не о лотусном подписывании, а принятой в Латвии электронной подписи.
В результате процесса подписывания, исходный файл вкладывается в файл .edoc (по сути zip) с метаданными, хешем и т.д.
Короче, после подписания получается новый файл, внутри которого лежит наш исходный.

Kee_Keekkenen
>а приаттачить (аплоад) в какой-нибудь документ через апплет можно?
У апплета есть параметр, куда ложить (аплодить) результирующий файл.
Я, конечно, могу подать урл на документ, но апплет не сможет его обработать ибо о специфике LN ничего не знает.
Т.е. если подавать URL, то мне нужно подавать URL на какую-то папку на сервере, куда можно свободно аплодить файлы.
Собственно, как бы часть вопроса и состояла в этом: как в Domino организовать папку, куда можно свободно аплодить файлы.

NetWood
>Может AJAX развернуть и потом агентом?
Посмотрел, что-то похожее.
Поставил в очередь.

ToxaRat
>поставь скрытый аплоад, где будет путь к твоему модифицированному файлу
Вот с этого, я, пожалуй, и попробую начать.
 

Leoric

Well-known member
15.10.2003
60
8
#7
Если у апплета есть доступ и к файлу и к сети, а судя по всему он есть. То я бы сделал на домине агента, либо сервлет, которому апплет будет POSTом отправлять файл и некий ключ (UNID?). По этому ключу агент-сервлет понимает где исходный документ и к чему надо аттачить полученный файл.

Примерно так. Вопросами видятся:
1. доступ к файловой системе из апплета (давно это было, вроде были какие-то большие траблы)
2. секьюрность передачи файлов сервер-аплет-сервер (https?)
 

Omh

Lotus team
04.07.2007
2 210
1
#8
ToxaRat
Слушай, а где указывать этот самый "путь к твоему модифицированному файлу"
Что-то я туплю
 

Omh

Lotus team
04.07.2007
2 210
1
#9
Leoric
Смотри, как раз в данный момент апплет после выполнения подписи пытается методом POST отослать данные по URL указаному в параметре апплета.
Как мне сделать агента, который мог бы ловить этот пост реквест и распарсить его?

/me чувствует себя тупицей :)
 

erdi

Well-known member
20.08.2008
265
17
#10
почта на JS
глянь эту ссылку, может натолкнет на что-то, там есть обзор использования агента через JS
 

Leoric

Well-known member
15.10.2003
60
8
#11
Вызов агента под веб - OpenAgent
Syntax
http://Host/Database/AgentName?OpenAgent
Examples
http://www.mercury.com/sales/leads.nsf/Pro...Leads?OpenAgent
Note Agents may only be referred to by name. The use of UNID is not supported when referring to an agent.

Посмотрите в хэлпе — Examples: Web agents, там есть как парсить GET запрос. В Table of CGI variable names есть доступные переменные (по идее надо доставать из Request_Content).

В принципе обработка POST будет стандартная для java, здесь поможет кучка статей в гугле.

Примеры кода работы постараюсь показать когда буду дома, если найду в своей свалархиве
 

NetWood

Lotus team
17.04.2008
372
19
#12
Посмотрите в хэлпе — Examples: Web agents, там есть как парсить GET запрос. В Table of CGI variable names есть доступные переменные (по идее надо доставать из Request_Content).
Как-то так
http://host/base.nsf/RC?OpenAgent&id=3...4257B0100775E01
Внутри
Код:
	Set db = s.CurrentDatabase	
Set ctx=s.DocumentContext
ConfirmUserID = Strright(ctx.Query_String(0), "id=")
Ну и в скрытытом аплоаде параметры так и передавать агенту.
 

Leoric

Well-known member
15.10.2003
60
8
#13
Код:
Sub Initialize

' Этот агент срабатывает из Веба при нажатии кнопки "Заказ" - посылает письмо-заказ
Dim s As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Set doc=s.DocumentContext
Set agentLog = New NotesLog("Agent log")
Call agentLog.OpenAgentLog


Set db=s.CurrentDatabase
Set memo = New NotesDocument(db)
Dim rt As NotesRichTextItem
Set rt = New NotesRichTextItem( memo, "Body" )
order = doc.Request_Content(0)	  ' содержимое запроса в виде: from=...&subject=...&body=...


pos = Instr(order,"&")					  ' извлечение первого параметра from= и
textFrom = Left(order,pos-1)			 ' присваивание его в поле SMTPOriginator:
order = Right(order, Len(order)-pos) ' ответ будет отсылаться по этому адресу
posEq = Instr(textFrom, "=")
memo.SMTPOriginator = Right (textFrom , Len(textFrom)-posEq)

' ..... все остальные обработки строки запроса

memo.Form = "Document"	
' отправка письма в базу где оно будет обработано как входящий заказ
Call memo.Send (False, "адрес@базы куда отправляем на обработку")	

Print |ответ клиенту|
Call agentLog.LogAction("создано и отправлено письмо") 
Call agentLog.Close
End Sub
Агент дергается из POST формы на странице заказа в запросе получает введенные данные и формирует письмо-заказ которое отправляет в базу для обработки.
Здесь можно видеть основной принцип, Set doc=s.DocumentContext -> контекст агента (док со спец полями из формы), order = doc.Request_Content(0) -> строка запроса
Сейчас подумал, задачи принимать файлы никогда не стояло, всё как-то параметры, а файла всё как-то на отдачу. Но думаю принцип тотже.

P.S. Не пинайте за такую крывущую обработку, это было в первые пол года работы)) Но оно еще живо, а значит имеет право на существование)
P.P.S. На Java не нашел реализации, кануло в лету при переезде по ходу
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 584
271
#14
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"класс:"</div></div><div class="sp-body"><div class="sp-content">
Код:
'encode возвращает вместо " " -> "+"
'http://docs.oracle.com/javase/1.4.2/docs/api/java/net/URLEncoder.html
Class HttpBase As ErrorHandlerWJ
Private curdoc As NotesDocument
Private ses As NotesSession
Private isPrintedHeader As Boolean
Private isPrintedEnd As Boolean
Private decoderClass As JavaClass
Private encoderClass As JavaClass
Private encoderObj As JavaObject
Private Contenttype As String
Private msgList List As String
Private msgCount As Long
Private errList List As String
Private errCount As Long
Sub New()
Set ses=New NotesSession
Set curdoc=ses.DocumentContext
Set encoderClass=jSession.Getclass({java/net/URLEncoder})
Set decoderClass=jSession.Getclass({java/net/URLDecoder})
Contenttype={text}
End Sub

Sub Delete
Me.Close
End Sub

Property Get CGIvar(xName As String) As String
CGIvar=curdoc.GetItemValue(xName)(0)
End Property

Private Property Set Content As String

End Property

Property Get GetRequestParams As Variant
On Error Goto ErrH
Dim s As String
s=Fulltrim(GetRequestQuery)
If Len(s)>0 Then
GetRequestParams=Split(s,{&})
Else
s=Fulltrim(GetRequestPost)
If Len(s)>0 Then GetRequestParams=Split(s,{&})
End If
Quit:
Exit Property
ErrH:
Me.PrintError(Me.RaiseError)
Resume Quit
End Property

Property Get GetRequestQuery As String
On Error Goto ErrH
'используется Query_String_Decoded - не чувствует разницы между "+" и " "
'это поведение типично и потому "+" -> " "
GetRequestQuery=curdoc.getItemValue("Query_String_Decoded")(0)
Quit:
Exit Property
ErrH:
Me.PrintError(Me.RaiseError)
Resume Quit
End Property

Property Get GetRequestPost As String
On Error Goto ErrH
GetRequestPost=curdoc.getItemValue("Request_Content")(0)
Quit:
Exit Property
ErrH:
Me.PrintError(Me.RaiseError)
Resume Quit
End Property

Property Get GetRequesPath As String
GetRequesPath=curdoc.getItemValueString("Path_Info_Decoded")
End Property

Sub PrintMsg(msg As String)
PrintHeader
msgList({message_} &Cstr(msgCount))=msg
msgCount=msgCount+1
End Sub

Function Decode(msg As String) As String
Decode=decoderClass.decode(msg)
End Function

Function DecodeUTF8(msg As String) As String
DecodeUTF8=decoderClass.decode(msg,{UTF-8})
End Function

Function DecodeCP1251(msg As String) As String
DecodeCP1251=decoderClass.decode(msg, {Cp1251})
End Function

Function DecodeAll(msg As String, enc As String) As String
DecodeAll=decoderClass.decode(msg, enc)
End Function

Function EncodeAll(msg As String, enc As String) As String
EncodeAll=encoderClass.encode(msg, enc)
End Function

Function Encode(msg As String) As String
Encode=encoderClass.encode(msg)
End Function

Sub PrintMsgEncoded(msg As String)
PrintHeader
msgList({messageEnc_} &Cstr(msgCount))=encoderClass.encode(msg)
End Sub

Private Function PrintHeader As Boolean
On Error Goto ErrH
If isPrintedHeader Then Exit Function
'возвращаем результат в UTF-8
Print {Content-Type: } &Contenttype &{; charset=UTF-8"} 'text/xml;application/xml;
'		Print {Content-Type: } &Contenttype &{; charset=Windows-1251"}
isPrintedHeader=True
Me.PrintHeader=True
Quit:
Exit Function
ErrH:
Error Err, RaiseError
End Function

Private Function PrintEnd As Boolean
If Not isPrintedHeader Then Exit Function
If isPrintedEnd Then Exit Function
isPrintedEnd=True
Me.PrintEnd=True
End Function

Private Sub PrintError(msg As String)
PrintHeader
errList({error_} &Cstr(errCount))=msg
errCount=errCount+1
End Sub

Sub Close
PrintEnd
End Sub
End Class

Class HttpBaseXML As HttpBase
Function PrintHeader As Boolean
Dim b As Boolean
b=HttpBase..PrintHeader
Me.PrintHeader=b
If Not b Then Exit Function
Print {<?xml version="1.0" encoding="UTF-8"?>}
Print {<response>}
End Function

Sub New()
Contenttype={text/xml}
End Sub

Sub PrintMsg(msg As String)
PrintHeader
Print {<message>} &msg &{</message>}
End Sub

Sub PrintMsgEncoded(msg As String)
PrintHeader
Print {<messageenc>} &encoderClass.encode(msg) &{</messageenc>}
End Sub

Function PrintEnd As Boolean
Dim b As Boolean
b=HttpBase..PrintEnd
Me.PrintEnd=b
If Not b Then Exit Function
Print {</response>}
End Function

Sub PrintError(msg As String)
Call HttpBase..PrintError(msg)
Print {<error><object>} & Typename(Me) &{</object><message>} &msg &{</message></error>}
End Sub
End Class

Class HttpBaseJSON As HttpBase
Function PrintHeader As Boolean
Dim b As Boolean
b=HttpBase..PrintHeader
Me.PrintHeader=b
If Not b Then Exit Function
'		Print |{"response":[|
Print |{|
End Function

Sub New
Contenttype="application/json"
End Sub

Function PrintEnd As Boolean
Dim b As Boolean
b=HttpBase..PrintEnd
Me.PrintEnd=b
If Not b Then Exit Function
'		Print |"end":"end"]}|
Print |"end":"end"}|'заглушка, чтобы не заморачиваться на оконечные запятые
End Function

'	Sub PrintMsg(msg As String)
'		PrintHeader
'		Print {"message":"} &msg &{",}
'	End Sub

'	Sub PrintMsgEncoded(msg As String)
'		PrintHeader
'		Print {"message_enc":"} &encoderClass.encode(msg) &{",}
'	End Sub

Sub PrintJSONvar(xName As String, xValue As String)
PrintHeader
Print {"} &xName &{":"} &xValue &{",}
End Sub

'	Sub PrintError(msg As String)
'		Call HttpBase..PrintError(msg)
'		Print |"error":{"object":"| & Typename(Me) &|", "message":"| &msg &|"},|
'	End Sub

Sub Close
'разделим потоки ошибок и сообщений
'выводим ошибки из буфера
Print |errors:[|
Forall e In errList
Print |{"| & Listtag(e) & |":{"object":"| & Typename(Me) &|", "message":"| & e &|"}},|
End Forall
'если первым елементом - errors[0]=="end" - нет ошибок
Print |"end"],| 'зглушка окончания списка ошибок
'выаодим сообщения из буфера
Print |messages:[|
Forall m In msgList
'			Print |{"| &Listtag(m) &|":"| &m &|"},|
Print |"| &m &|",|
End Forall
'если первым елементом - messages[0]=="end" - нет сообщений
Print |"end"],| 'заглушка окончания списка сообщений
HttpBase..Close
End Sub
End Class

Class HttpObj As HttpBaseJSON
End Class
мне кажется я выкладывал

этот класс для обработки GET и POST типа:v=httpObj.GetRequestParams
также - может выводить результат, в т.ч. в JSON
декодит и энкодит - это важно для не анлийских языков
 

Omh

Lotus team
04.07.2007
2 210
1
#15
Товарищи, заработало.

Если коротко, то получилось так: на офф. форуме прочитал что домино при аплоде валидейтит пост мессыдж относительно формы в базе, которая указана в самом постмесседже.
Сделал простенькую форму с одним FUC полем, посабмиттил её 100500 раз, почитал Request Body.
Вместе с разарботчиком апплета подделали такой же Request Body и начали засылать.
Надо подделывать вплоть до всяких мелочей ;)

Авторизация апплета тупо через посылку куки "DomAuthSessId" от залогиненного пользователя.
UNID формы в коде FUC для POST сообщения вычисляется динамически.

Речь идёт про вот этот кусок "%%File.c2256eec003c58a5.7f505793c5d3868fc2257b0100376e50.$Body.0.70">, где
c2256eec003c58a5 - replica id базы
7f505793c5d3868fc2257b0100376e50 - UNID формы, где расположен FUC
0.70 - смещение FUC на форме.

Сильно помогли знания из своей же темы: http://codeby.net/forum/threads/42504.html

Пока буду доделывать.
Будут вопросы - ю а велком!!



Добавлено: Постится примерно так:
Referer - http://SERVER/PATH.nsf/UploadForm?OpenForm
Куда постится - http://SERVER/PATH.nsf/UploadForm?OpenForm&Seq=1

UploadForm - простенькая форма в базе, POST мессыдж который мы и фейковали в апплете.
 

Кирилл Шваб

Well-known member
30.06.2006
145
4
#16
Omh,

только учитывай, что при редактировании формы/подформы с File Upload Control идентификатор $Body... будет меняться.

По-моему даже при простом пересохранении формы. 100% не помню, но вроде так.
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 584
271
#17
Omh,

только учитывай, что при редактировании формы/подформы с File Upload Control идентификатор $Body... будет меняться.

По-моему даже при простом пересохранении формы. 100% не помню, но вроде так.
поэтому предложено было решение с сабформой тогда форму редактировать можно, а сабформу какбы и незачем :)
 

Omh

Lotus team
04.07.2007
2 210
1
#18
Кирилл Шваб
Не-не, оффсет сменится только в том случае, если ты перед FUC полем начнёшь пробивать энтера.
Я этого делать не собираюсь.
Аплод форма у меня статична, оффсет известен, всё работает :)

lmike
Да, это всё пройдено ещё в 2011 году в той теме, которую я указал в после с решением.