summaryrefslogtreecommitdiff
path: root/htroot/MessageSend_p.java
blob: 57271bc004cd889aed362896a0df2b763d3e1738 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
//MessageSend_p.java
//-----------------------
//part of the AnomicHTTPD caching proxy
//(C) by Michael Peter Christen; mc@yacy.net
//first published on http://www.anomic.de
//Frankfurt, Germany, 2004
//Last major change: 28.06.2003

//This program is free software; you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation; either version 2 of the License, or
//(at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


//You must compile this file with
//javac -classpath .:../Classes MessageSend_p.java
//if the shell's current path is HTROOT

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Date;
import java.util.Map;

import org.apache.http.entity.mime.content.ContentBody;

import net.yacy.cora.date.GenericFormatter;
import net.yacy.cora.document.encoding.ASCII;
import net.yacy.cora.document.encoding.UTF8;
import net.yacy.cora.document.id.MultiProtocolURL;
import net.yacy.cora.protocol.RequestHeader;
import net.yacy.kelondro.util.FileUtils;
import net.yacy.peers.Network;
import net.yacy.peers.Protocol;
import net.yacy.peers.Protocol.Post;
import net.yacy.peers.Seed;
import net.yacy.peers.SeedDB;
import net.yacy.search.Switchboard;
import net.yacy.search.SwitchboardConstants;
import net.yacy.server.serverObjects;
import net.yacy.server.serverSwitch;
import net.yacy.utils.crypt;

public class MessageSend_p {

    public static String dateString(final Date date) {
        return GenericFormatter.SIMPLE_FORMATTER.format(date);
    }


    public static serverObjects respond(@SuppressWarnings("unused") final RequestHeader header, final serverObjects post, final serverSwitch env) {
        final Switchboard sb = (Switchboard) env;
        final serverObjects prop = new serverObjects();

        if ((post == null) || (post.get("hash","").isEmpty())) {
            prop.put("mode", "3");
            return prop;
        }

        final String hash = post.get("hash", "");
        String subject = post.get("subject", "");
        String message = post.get("message", "");

        if ((message.isEmpty()) || (post.containsKey("preview"))) {
            if (post.containsKey("preview")) {
                prop.put("mode", "1");
            } else {
                prop.put("mode", "0");
            }

            // open an editor page for the message
            // first ask if the other peer is online, and also what kind of document it accepts
            Seed seed = sb.peers.getConnected(ASCII.getBytes(hash));
            if (seed != null) {
                for (final String ip : seed.getIPs()) {
                	Map<String, String> result = null;
                	MultiProtocolURL targetBaseURL = null;
            		final String targetBaseURLStr = seed.getPublicURL(ip,
            				sb.getConfigBool(SwitchboardConstants.NETWORK_PROTOCOL_HTTPS_PREFERRED,
            						SwitchboardConstants.NETWORK_PROTOCOL_HTTPS_PREFERRED_DEFAULT));
                	try {
                		targetBaseURL = new MultiProtocolURL(targetBaseURLStr);
                		result = Protocol.permissionMessage(targetBaseURL, seed, sb);
                	} catch(final MalformedURLException e) {
                		Network.log.warn("yacyClient.permissionMessage malformed target peer URL :" + targetBaseURLStr);
                	} catch(final Exception e) {
                        // most probably a network time-out exception
                        Network.log.warn("yacyClient.permissionMessage error:" + e.getMessage());
                		if(targetBaseURL.isHTTPS()) {
                			try {
                				/* Request made over https : retry using http on the same IP as a fallback */
                				targetBaseURL = seed.getPublicMultiprotocolURL(ip, false);
                				result = Protocol.permissionMessage(targetBaseURL, seed, sb);
                				if(result != null) {
                					/* Got a successfull result with http : mark now SSl as not available ont the target peer */
                					seed.setFlagSSLAvailable(false);
                					sb.peers.updateConnected(seed);
                				}
                			} catch (final IOException e2) {
                        		Network.log.warn("yacyClient.postMessage error:" + e2.getMessage());
                			}
                		}
                	}
                    //System.out.println("DEBUG: permission request result = " + result.toString());
                    String peerName;
                    Seed targetPeer = null;
                    if (hash.equals(sb.peers.mySeed().hash)) {
                        peerName = sb.peers.mySeed().get(Seed.NAME, "nameless");
                    } else {
                        targetPeer = sb.peers.getConnected(hash);
                        if (targetPeer == null) {
                            peerName = "nameless";
                        } else {
                            peerName = targetPeer.get(Seed.NAME, "nameless");
                        }
                    }

                    prop.putXML("mode_permission_peerName", peerName);
                    final String response = (result == null) ? null : result.get("response");
                    if (response == null || result == null) {
                        // we don't have permission or other peer does not exist
                        prop.put("mode_permission", "0");
                        if (targetPeer != null) {
                            sb.peers.peerActions.interfaceDeparture(targetPeer, ip);
                        }
                    } else {
                    	
                        prop.put("mode_permission", "1");

                        // write input form
                        try {
                            final int messagesize = Integer.parseInt(result.get("messagesize"));
                            final int attachmentsize = Integer.parseInt(result.get("attachmentsize"));

                            prop.putXML("mode_permission_response", response);
                            prop.put("mode_permission_messagesize", messagesize);
                            prop.put("mode_permission_attachmentsize", attachmentsize);
                            prop.putXML("mode_permission_subject", subject);
                            prop.putXML("mode_permission_message", message);
                            prop.putHTML("mode_permission_hash", hash);
                            if (post.containsKey("preview")) {
                                prop.putWiki("mode_permission_previewmessage", message);
                            }

                        } catch (final NumberFormatException e) {
                            // "unresolved pattern", the remote peer is alive but had an exception
                            prop.put("mode_permission", "2");
                        }
                    }
                }
            } else { // seed == null
                prop.put("mode_permission", "0");
                prop.putXML("mode_permission_peerName", "a passive peer");
            }
        } else {
            prop.put("mode", "2");
            // send written message to peer
            try {
                prop.put("mode_status", "0");
                int messagesize = post.getInt("messagesize", 0);
                //int attachmentsize = Integer.parseInt(post.get("attachmentsize", "0"));

                if (messagesize < 1000) messagesize = 1000; // debug
                if (subject.length() > 100) subject = subject.substring(0, 100);
                if (message.length() > messagesize) message = message.substring(0, messagesize);
                final byte[] mb = UTF8.getBytes(message);
                SeedDB seedDB = sb.peers;
                // prepare request
                final String salt = crypt.randomSalt();

                // send request
                final Map<String, ContentBody> parts = Protocol.basicRequestParts(sb, hash, salt);
                parts.put("process", UTF8.StringBody("post"));
                parts.put("myseed", UTF8.StringBody(seedDB.mySeed().genSeedStr(salt)));
                parts.put("subject", UTF8.StringBody(subject));
                parts.put("message", UTF8.StringBody(mb));
                final Seed seed = seedDB.getConnected(ASCII.getBytes(hash));
                boolean preferHttps = sb.getConfigBool(SwitchboardConstants.NETWORK_PROTOCOL_HTTPS_PREFERRED,
						SwitchboardConstants.NETWORK_PROTOCOL_HTTPS_PREFERRED_DEFAULT);
                Post post1 = null;
                for(final String ip : seed.getIPs()) {
                	MultiProtocolURL targetBaseURL = null;
                	try {
                		targetBaseURL = seed.getPublicMultiprotocolURL(ip, preferHttps);
                		post1 = new Post(targetBaseURL, seed.hash, "/yacy/message.html", parts, 20000);
                	} catch(final MalformedURLException e) {
                		Network.log.warn("yacyClient.postMessage malformed target peer URL when using ip " + ip);
                	} catch (final IOException e) {
                		Network.log.warn("yacyClient.postMessage error:" + e.getMessage());
                		if(targetBaseURL.isHTTPS()) {
                			try {
                				/* Request made over https : retry using http on the same IP as a fallback */
                				targetBaseURL = seed.getPublicMultiprotocolURL(ip, false);
                				post1 = new Post(targetBaseURL, seed.hash, "/yacy/message.html", parts, 20000);
                				if(post1 != null) {
                					/* Got a successfull result with http : mark now SSl as not available ont the target peer */
                					seed.setFlagSSLAvailable(false);
                				}
                			} catch (final IOException e2) {
                        		Network.log.warn("yacyClient.postMessage error:" + e2.getMessage());
                			}
                		}
                	}
                	
                	if (post1 != null) {
                		break;
                	}
                	seedDB.peerActions.interfaceDeparture(seed, ip);
                }
                final Map<String, String> result1 = post1 == null ? null : FileUtils.table(post1.getResult());
                final Map<String, String> result = result1;

                if(result != null) {
                	// message has been sent
                	prop.put("mode_status_response", result.get("response"));
                } else {
                    prop.put("mode_status", "1");

                    // "unresolved pattern", the remote peer is alive but had an exception
                    prop.putXML("mode_status_message", message);
                }

            } catch (final NumberFormatException e) {
                prop.put("mode_status", "1");

                // "unresolved pattern", the remote peer is alive but had an exception
                prop.putXML("mode_status_message", message);
            }
        }
        return prop;
    }
}