コード例 #1
0
  public void dump(PrintWriter out) {
    out.println("SpdyConnection open=" + channels.size() + " outQ:" + outQueue.size());
    for (SpdyStream str : channels.values()) {
      str.dump(out);
    }

    out.println();
  }
コード例 #2
0
  public SpdyStream get(String host, String url) {
    SpdyStream sch = new SpdyStream(this);
    sch.getRequest().addHeader("host", host);
    sch.getRequest().addHeader("url", url);

    sch.send();

    return sch;
  }
コード例 #3
0
  // Framing error or shutdown- close all streams.
  public void abort(String msg) {
    System.err.println(msg);
    inClosed = true;

    List<Integer> ch = new ArrayList<>(channels.keySet());
    for (Integer i : ch) {
      SpdyStream stream = channels.remove(i);
      if (stream != null) {
        stream.onReset();
      }
    }
  }
コード例 #4
0
  @Override
  public void receive(final SpdyStream stream) throws IOException {
    List<String> requestHeaders = stream.getRequestHeaders();
    String path = null;
    for (int i = 0; i < requestHeaders.size(); i += 2) {
      String s = requestHeaders.get(i);
      if ("url".equals(s)) {
        path = requestHeaders.get(i + 1);
        break;
      }
    }

    if (path == null) {
      // TODO: send bad request error
      throw new AssertionError();
    }

    File file = new File(baseDirectory + path);

    if (file.exists() && !file.isDirectory()) {
      serveFile(stream, file);
    } else {
      send404(stream, path);
    }
  }
コード例 #5
0
 private void send404(SpdyStream stream, String path) throws IOException {
   List<String> responseHeaders =
       Arrays.asList(
           "status", "404",
           "version", "HTTP/1.1",
           "content-type", "text/plain");
   OutputStream out = stream.reply(responseHeaders);
   String text = "Not found: " + path;
   out.write(text.getBytes("UTF-8"));
   out.close();
 }
コード例 #6
0
 private void serveFile(SpdyStream stream, File file) throws IOException {
   InputStream in = new FileInputStream(file);
   byte[] buffer = new byte[8192];
   OutputStream out =
       stream.reply(
           Arrays.asList(
               "status", "200",
               "version", "HTTP/1.1",
               "content-type", contentType(file)));
   int count;
   while ((count = in.read(buffer)) != -1) {
     out.write(buffer, 0, count);
   }
   out.close();
 }
コード例 #7
0
  /**
   * Process a SPDY connection. Called in the input thread, should not block.
   *
   * @throws IOException
   */
  protected int handleFrame() throws IOException {
    if (inFrame.c) {
      switch (inFrame.type) {
        case TYPE_SETTINGS:
          {
            int cnt = inFrame.readInt();
            for (int i = 0; i < cnt; i++) {
              inFrame.readByte();
              inFrame.read24();
              inFrame.readInt();
            }
            // TODO: save/interpret settings
            break;
          }
        case TYPE_GOAWAY:
          {
            int lastStream = inFrame.readInt();
            log.info("GOAWAY last=" + lastStream);

            // Server will shut down - but will keep processing the current requests,
            // up to lastStream. If we sent any new ones - they need to be canceled.
            abort("GO_AWAY", lastStream);
            goAway = lastStream;
            return CLOSE;
          }
        case TYPE_RST_STREAM:
          {
            inFrame.streamId = inFrame.read32();
            int errCode = inFrame.read32();
            if (SpdyContext.debug) {
              trace(
                  "> RST "
                      + inFrame.streamId
                      + " "
                      + ((errCode < RST_ERRORS.length)
                          ? RST_ERRORS[errCode]
                          : Integer.valueOf(errCode)));
            }
            SpdyStream sch;
            synchronized (channels) {
              sch = channels.remove(Integer.valueOf(inFrame.streamId));
            }
            // if RST stream is for a closed channel - we can ignore.
            if (sch != null) {
              sch.onReset();
            }

            inFrame = null;
            break;
          }
        case TYPE_SYN_STREAM:
          {
            SpdyStream ch = getSpdyContext().getStream(this);

            synchronized (channels) {
              channels.put(Integer.valueOf(inFrame.streamId), ch);
            }

            try {
              ch.onCtlFrame(inFrame);
              inFrame = null;
            } catch (Throwable t) {
              log.log(Level.SEVERE, "Error parsing head SYN_STREAM", t);
              abort("Error reading headers " + t);
              return CLOSE;
            }
            spdyContext.onStream(this, ch);
            break;
          }
        case TYPE_SYN_REPLY:
          {
            SpdyStream sch;
            synchronized (channels) {
              sch = channels.get(Integer.valueOf(inFrame.streamId));
            }
            if (sch == null) {
              abort("Missing channel");
              return CLOSE;
            }
            try {
              sch.onCtlFrame(inFrame);
              inFrame = null;
            } catch (Throwable t) {
              log.info("Error parsing head SYN_STREAM" + t);
              abort("Error reading headers " + t);
              return CLOSE;
            }
            break;
          }
        case TYPE_PING:
          {
            SpdyFrame oframe = getSpdyContext().getFrame();
            oframe.type = TYPE_PING;
            oframe.c = true;

            oframe.append32(inFrame.read32());
            oframe.pri = 0x80;

            send(oframe, null);
            break;
          }
      }
    } else {
      // Data frame
      SpdyStream sch;
      synchronized (channels) {
        sch = channels.get(Integer.valueOf(inFrame.streamId));
      }
      if (sch == null) {
        abort("Missing channel");
        return CLOSE;
      }
      sch.onDataFrame(inFrame);
      synchronized (channels) {
        if (sch.finRcvd && sch.finSent) {
          channels.remove(Integer.valueOf(inFrame.streamId));
        }
      }
      inFrame = null;
    }
    return LONG;
  }