1   /* Copyright 2002-2024 CS GROUP
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.orekit.gnss.metric.ntrip;
18  
19  import java.io.BufferedReader;
20  import java.io.FileInputStream;
21  import java.io.IOException;
22  import java.io.InputStreamReader;
23  import java.io.OutputStream;
24  import java.io.OutputStreamWriter;
25  import java.net.ServerSocket;
26  import java.net.Socket;
27  import java.nio.charset.StandardCharsets;
28  import java.util.HashMap;
29  import java.util.Map;
30  import java.util.concurrent.CountDownLatch;
31  import java.util.concurrent.Executors;
32  import java.util.concurrent.TimeUnit;
33  import java.util.concurrent.atomic.AtomicReference;
34  
35  public class DummyServer {
36  
37      private final String[]            fileNames;
38      private final ServerSocket        server;
39      private final Map<String, String> requestProperties;
40      private final CountDownLatch      done = new CountDownLatch(1);
41      private final AtomicReference<Exception> error = new AtomicReference<>(null);
42  
43      public DummyServer(final String... fileNames) throws IOException {
44          this.fileNames         = fileNames.clone();
45          this.server            = new ServerSocket(0);
46          this.requestProperties = new HashMap<>();
47      }
48  
49      public int getServerPort() {
50          return server.getLocalPort();
51      }
52  
53      public String getRequestProperty(final String key) {
54          return requestProperties.get(key);
55      }
56  
57      public void await(long timeout, TimeUnit unit) throws Exception {
58          done.await(timeout, unit);
59          final Exception e = error.get();
60          if (e != null)
61              throw e;
62      }
63  
64      public void run() {
65          Executors.newSingleThreadExecutor().execute(() -> {
66              try {
67  
68                  for (String fileName : fileNames) {
69                      // get connection from client
70                      final Socket             socket = server.accept();
71                      final BufferedReader     br1    = new BufferedReader(new InputStreamReader(socket.getInputStream(),
72                                                                                                 StandardCharsets.UTF_8));
73  
74                      // read request until an empty line is found
75                      for (String line = br1.readLine(); line != null; line = br1.readLine()) {
76                          if (line.trim().isEmpty()) {
77                              break;
78                          } else {
79                              final int colon = line.indexOf(':');
80                              if (colon > 0) {
81                                  requestProperties.put(line.substring(0, colon), line.substring(colon + 2));
82                              }
83                          }
84                      }
85  
86                      // serve the file content
87                      if (fileName.endsWith(".txt")) {
88                          // serve the file as text
89                          final OutputStreamWriter osw =
90                                          new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8);
91                          try (FileInputStream   fis = new FileInputStream(fileName);
92                               InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);
93                               BufferedReader    br2 = new BufferedReader(isr)) {
94                              for (String line = br2.readLine(); line != null; line = br2.readLine()) {
95                                  osw.write(line);
96                                  osw.write("\r\n");
97                                  osw.flush();
98                              }
99                          }
100                     } else {
101                         // serve the file as binary
102                         final OutputStream os = socket.getOutputStream();
103                         try (FileInputStream fis = new FileInputStream(fileName)) {
104                             final byte[] buffer = new byte[4096];
105                             for (int r = fis.read(buffer); r >= 0; r = fis.read(buffer)) {
106                                 os.write(buffer, 0, r);
107                             }
108                         }
109                     }
110 
111                     socket.close();
112                 }
113                 done.countDown();
114 
115             } catch (IOException ioe) {
116                 error.set(ioe);
117                 done.countDown();
118                 throw new RuntimeException(ioe);
119             }
120         });
121     }
122 
123 }