private int write(ByteBuffer buf) { Debug.Assert(_fd != null); if (AssemblyUtil.isMono) { // // Mono on Android and iOS don't support the use of synchronous socket // operations on a non-blocking socket. Returning 0 here forces the caller to schedule // an asynchronous operation. // return(0); } int packetSize = buf.remaining(); if (AssemblyUtil.isWindows) { // // On Windows, limiting the buffer size is important to prevent // poor throughput performances when transfering large amount of // data. See Microsoft KB article KB823764. // if (_maxSendPacketSize > 0 && packetSize > _maxSendPacketSize / 2) { packetSize = _maxSendPacketSize / 2; } } int sent = 0; while (buf.hasRemaining()) { try { int ret = _fd.Send(buf.rawBytes(), buf.position(), packetSize, SocketFlags.None); Debug.Assert(ret > 0); sent += ret; buf.position(buf.position() + ret); if (packetSize > buf.remaining()) { packetSize = buf.remaining(); } } catch (SocketException ex) { if (Network.wouldBlock(ex)) { return(sent); } else if (Network.connectionLost(ex)) { throw new Ice.ConnectionLostException(ex); } throw new Ice.SocketException(ex); } } return(sent); }
private int write(ByteBuffer buf) { Debug.Assert(_fd != null); int packetSize = buf.remaining(); if (AssemblyUtil.platform_ == AssemblyUtil.Platform.Windows) { // // On Windows, limiting the buffer size is important to prevent // poor throughput performances when transfering large amount of // data. See Microsoft KB article KB823764. // if (_maxSendPacketSize > 0 && packetSize > _maxSendPacketSize / 2) { packetSize = _maxSendPacketSize / 2; } } int sent = 0; while (buf.hasRemaining()) { try { int ret = _fd.Send(buf.rawBytes(), buf.position(), packetSize, SocketFlags.None); Debug.Assert(ret > 0); sent += ret; buf.position(buf.position() + ret); if (packetSize > buf.remaining()) { packetSize = buf.remaining(); } } catch (SocketException ex) { if (Network.wouldBlock(ex)) { return(sent); } else if (Network.connectionLost(ex)) { throw new Ice.ConnectionLostException(ex); } throw new Ice.SocketException(ex); } } return(sent); }
private int read(ByteBuffer buf) { Debug.Assert(_fd != null); #if COMPACT || SILVERLIGHT // // Silverlight and the Compact .NET Framework don't // support the use of synchronous socket operations on a // non-blocking socket. Returning 0 here forces the caller // to schedule an asynchronous operation. // return(0); #else int read = 0; while (buf.hasRemaining()) { try { int ret = _fd.Receive(buf.rawBytes(), buf.position(), buf.remaining(), SocketFlags.None); if (ret == 0) { throw new Ice.ConnectionLostException(); } read += ret; buf.position(buf.position() + ret); } catch (SocketException ex) { if (Network.wouldBlock(ex)) { return(read); } else if (Network.interrupted(ex)) { continue; } else if (Network.connectionLost(ex)) { throw new Ice.ConnectionLostException(ex); } throw new Ice.SocketException(ex); } } return(read); #endif }
private int read(ByteBuffer buf) { Debug.Assert(_fd != null); if (AssemblyUtil.isMono) { // // Mono on Android and iOS don't support the use of synchronous socket // operations on a non-blocking socket. Returning 0 here forces the caller to schedule // an asynchronous operation. // return(0); } int read = 0; while (buf.hasRemaining()) { try { int ret = _fd.Receive(buf.rawBytes(), buf.position(), buf.remaining(), SocketFlags.None); if (ret == 0) { throw new Ice.ConnectionLostException(); } read += ret; buf.position(buf.position() + ret); } catch (SocketException ex) { if (Network.wouldBlock(ex)) { return(read); } else if (Network.interrupted(ex)) { continue; } else if (Network.connectionLost(ex)) { throw new Ice.ConnectionLostException(ex); } throw new Ice.SocketException(ex); } } return(read); }
internal int isCompleteMessage(ByteBuffer buf, int begin, int end) { byte[] raw = buf.rawBytes(); int p = begin; // // Skip any leading CR-LF characters. // while (p < end) { byte ch = raw[p]; if (ch != (byte)'\r' && ch != (byte)'\n') { break; } ++p; } // // Look for adjacent CR-LF/CR-LF or LF/LF. // bool seenFirst = false; while (p < end) { byte ch = raw[p++]; if (ch == (byte)'\n') { if (seenFirst) { return(p); } else { seenFirst = true; } } else if (ch != (byte)'\r') { seenFirst = false; } } return(-1); }
private int read(ByteBuffer buf) { Debug.Assert(_fd != null); int read = 0; while (buf.hasRemaining()) { try { int ret = _fd.Receive(buf.rawBytes(), buf.position(), buf.remaining(), SocketFlags.None); if (ret == 0) { throw new Ice.ConnectionLostException(); } read += ret; buf.position(buf.position() + ret); } catch (SocketException ex) { if (Network.wouldBlock(ex)) { return(read); } else if (Network.interrupted(ex)) { continue; } else if (Network.connectionLost(ex)) { throw new Ice.ConnectionLostException(ex); } throw new Ice.SocketException(ex); } } return(read); }
internal bool parse(ByteBuffer buf, int begin, int end) { byte[] raw = buf.rawBytes(); int p = begin; int start = 0; const char CR = '\r'; const char LF = '\n'; if (_state == State.Complete) { _state = State.Init; } while (p != end && _state != State.Complete) { char c = (char)raw[p]; switch (_state) { case State.Init: { _method = new StringBuilder(); _uri = new StringBuilder(); _versionMajor = -1; _versionMinor = -1; _status = -1; _reason = ""; _headers.Clear(); _state = State.Type; continue; } case State.Type: { if (c == CR || c == LF) { break; } else if (c == 'H') { // // Could be the start of "HTTP/1.1" or "HEAD". // _state = State.TypeCheck; break; } else { _state = State.Request; continue; } } case State.TypeCheck: { if (c == 'T') // Continuing "H_T_TP/1.1" { _state = State.Response; } else if (c == 'E') // Expecting "HEAD" { _state = State.Request; _method.Append('H'); _method.Append('E'); } else { throw new WebSocketException("malformed request or response"); } break; } case State.Request: { _type = Type.Request; _state = State.RequestMethod; continue; } case State.RequestMethod: { if (c == ' ' || c == CR || c == LF) { _state = State.RequestMethodSP; continue; } _method.Append(c); break; } case State.RequestMethodSP: { if (c == ' ') { break; } else if (c == CR || c == LF) { throw new WebSocketException("malformed request"); } _state = State.RequestURI; continue; } case State.RequestURI: { if (c == ' ' || c == CR || c == LF) { _state = State.RequestURISP; continue; } _uri.Append(c); break; } case State.RequestURISP: { if (c == ' ') { break; } else if (c == CR || c == LF) { throw new WebSocketException("malformed request"); } _state = State.Version; continue; } case State.RequestLF: { if (c != LF) { throw new WebSocketException("malformed request"); } _state = State.HeaderFieldStart; break; } case State.HeaderFieldStart: { // // We've already seen a LF to reach this state. // // Another CR or LF indicates the end of the header fields. // if (c == CR) { _state = State.HeaderFieldEndLF; break; } else if (c == LF) { _state = State.Complete; break; } else if (c == ' ') { // // Could be a continuation line. // _state = State.HeaderFieldContStart; break; } _state = State.HeaderFieldNameStart; continue; } case State.HeaderFieldContStart: { if (c == ' ') { break; } _state = State.HeaderFieldCont; start = p; continue; } case State.HeaderFieldCont: { if (c == CR || c == LF) { if (p > start) { if (_headerName.Length == 0) { throw new WebSocketException("malformed header"); } Debug.Assert(_headers.ContainsKey(_headerName)); string s = _headers[_headerName]; StringBuilder newValue = new StringBuilder(s); newValue.Append(' '); for (int i = start; i < p; ++i) { newValue.Append((char)raw[i]); } _headers[_headerName] = newValue.ToString(); _state = c == CR ? State.HeaderFieldLF : State.HeaderFieldStart; } else { // // Could mark the end of the header fields. // _state = c == CR ? State.HeaderFieldEndLF : State.Complete; } } break; } case State.HeaderFieldNameStart: { Debug.Assert(c != ' '); start = p; _headerName = ""; _state = State.HeaderFieldName; continue; } case State.HeaderFieldName: { if (c == ' ' || c == ':') { _state = State.HeaderFieldNameEnd; continue; } else if (c == CR || c == LF) { throw new WebSocketException("malformed header"); } break; } case State.HeaderFieldNameEnd: { if (_headerName.Length == 0) { StringBuilder str = new StringBuilder(); for (int i = start; i < p; ++i) { str.Append((char)raw[i]); } _headerName = str.ToString().ToLower(); // // Add a placeholder entry if necessary. // if (!_headers.ContainsKey(_headerName)) { _headers[_headerName] = ""; _headerNames[_headerName] = str.ToString(); } } if (c == ' ') { break; } else if (c != ':' || p == start) { throw new WebSocketException("malformed header"); } _state = State.HeaderFieldValueStart; break; } case State.HeaderFieldValueStart: { if (c == ' ') { break; } // // Check for "Name:\r\n" // if (c == CR) { _state = State.HeaderFieldLF; break; } else if (c == LF) { _state = State.HeaderFieldStart; break; } start = p; _state = State.HeaderFieldValue; continue; } case State.HeaderFieldValue: { if (c == CR || c == LF) { _state = State.HeaderFieldValueEnd; continue; } break; } case State.HeaderFieldValueEnd: { Debug.Assert(c == CR || c == LF); if (p > start) { StringBuilder str = new StringBuilder(); for (int i = start; i < p; ++i) { str.Append((char)raw[i]); } string s = null; if (!_headers.TryGetValue(_headerName, out s) || s.Length == 0) { _headers[_headerName] = str.ToString(); } else { _headers[_headerName] = s + ", " + str.ToString(); } } if (c == CR) { _state = State.HeaderFieldLF; } else { _state = State.HeaderFieldStart; } break; } case State.HeaderFieldLF: { if (c != LF) { throw new WebSocketException("malformed header"); } _state = State.HeaderFieldStart; break; } case State.HeaderFieldEndLF: { if (c != LF) { throw new WebSocketException("malformed header"); } _state = State.Complete; break; } case State.Version: { if (c != 'H') { throw new WebSocketException("malformed version"); } _state = State.VersionH; break; } case State.VersionH: { if (c != 'T') { throw new WebSocketException("malformed version"); } _state = State.VersionHT; break; } case State.VersionHT: { if (c != 'T') { throw new WebSocketException("malformed version"); } _state = State.VersionHTT; break; } case State.VersionHTT: { if (c != 'P') { throw new WebSocketException("malformed version"); } _state = State.VersionHTTP; break; } case State.VersionHTTP: { if (c != '/') { throw new WebSocketException("malformed version"); } _state = State.VersionMajor; break; } case State.VersionMajor: { if (c == '.') { if (_versionMajor == -1) { throw new WebSocketException("malformed version"); } _state = State.VersionMinor; break; } else if (c < '0' || c > '9') { throw new WebSocketException("malformed version"); } if (_versionMajor == -1) { _versionMajor = 0; } _versionMajor *= 10; _versionMajor += (int)(c - '0'); break; } case State.VersionMinor: { if (c == CR) { if (_versionMinor == -1 || _type != Type.Request) { throw new WebSocketException("malformed version"); } _state = State.RequestLF; break; } else if (c == LF) { if (_versionMinor == -1 || _type != Type.Request) { throw new WebSocketException("malformed version"); } _state = State.HeaderFieldStart; break; } else if (c == ' ') { if (_versionMinor == -1 || _type != Type.Response) { throw new WebSocketException("malformed version"); } _state = State.ResponseVersionSP; break; } else if (c < '0' || c > '9') { throw new WebSocketException("malformed version"); } if (_versionMinor == -1) { _versionMinor = 0; } _versionMinor *= 10; _versionMinor += (c - '0'); break; } case State.Response: { _type = Type.Response; _state = State.VersionHT; continue; } case State.ResponseVersionSP: { if (c == ' ') { break; } _state = State.ResponseStatus; continue; } case State.ResponseStatus: { // TODO: Is reason string optional? if (c == CR) { if (_status == -1) { throw new WebSocketException("malformed response status"); } _state = State.ResponseLF; break; } else if (c == LF) { if (_status == -1) { throw new WebSocketException("malformed response status"); } _state = State.HeaderFieldStart; break; } else if (c == ' ') { if (_status == -1) { throw new WebSocketException("malformed response status"); } _state = State.ResponseReasonStart; break; } else if (c < '0' || c > '9') { throw new WebSocketException("malformed response status"); } if (_status == -1) { _status = 0; } _status *= 10; _status += (c - '0'); break; } case State.ResponseReasonStart: { // // Skip leading spaces. // if (c == ' ') { break; } _state = State.ResponseReason; start = p; continue; } case State.ResponseReason: { if (c == CR || c == LF) { if (p > start) { StringBuilder str = new StringBuilder(); for (int i = start; i < p; ++i) { str.Append((char)raw[i]); } _reason = str.ToString(); } _state = c == CR ? State.ResponseLF : State.HeaderFieldStart; } break; } case State.ResponseLF: { if (c != LF) { throw new WebSocketException("malformed status line"); } _state = State.HeaderFieldStart; break; } case State.Complete: { Debug.Assert(false); // Shouldn't reach break; } } ++p; } return(_state == State.Complete); }
private int write(ByteBuffer buf) { Debug.Assert(_fd != null); #if COMPACT || SILVERLIGHT // // Silverlight and the Compact .NET Frameworks don't // support the use of synchronous socket operations on a // non-blocking socket. Returning 0 here forces the caller // to schedule an asynchronous operation. // return 0; #else int packetSize = buf.remaining(); if(AssemblyUtil.platform_ == AssemblyUtil.Platform.Windows) { // // On Windows, limiting the buffer size is important to prevent // poor throughput performances when transfering large amount of // data. See Microsoft KB article KB823764. // if(_maxSendPacketSize > 0 && packetSize > _maxSendPacketSize / 2) { packetSize = _maxSendPacketSize / 2; } } int sent = 0; while(buf.hasRemaining()) { try { int ret = _fd.Send(buf.rawBytes(), buf.position(), packetSize, SocketFlags.None); Debug.Assert(ret > 0); sent += ret; buf.position(buf.position() + ret); if(packetSize > buf.remaining()) { packetSize = buf.remaining(); } } catch(SocketException ex) { if(Network.wouldBlock(ex)) { return sent; } else if(Network.connectionLost(ex)) { throw new Ice.ConnectionLostException(ex); } throw new Ice.SocketException(ex); } } return sent; #endif }
private int read(ByteBuffer buf) { Debug.Assert(_fd != null); #if COMPACT || SILVERLIGHT // // Silverlight and the Compact .NET Framework don't // support the use of synchronous socket operations on a // non-blocking socket. Returning 0 here forces the caller // to schedule an asynchronous operation. // return 0; #else int read = 0; while(buf.hasRemaining()) { try { int ret = _fd.Receive(buf.rawBytes(), buf.position(), buf.remaining(), SocketFlags.None); if(ret == 0) { throw new Ice.ConnectionLostException(); } read += ret; buf.position(buf.position() + ret); } catch(SocketException ex) { if(Network.wouldBlock(ex)) { return read; } else if(Network.interrupted(ex)) { continue; } else if(Network.connectionLost(ex)) { throw new Ice.ConnectionLostException(ex); } throw new Ice.SocketException(ex); } } return read; #endif }
private int write(ByteBuffer buf) { Debug.Assert(_fd != null); int packetSize = buf.remaining(); if(AssemblyUtil.platform_ == AssemblyUtil.Platform.Windows) { // // On Windows, limiting the buffer size is important to prevent // poor throughput performances when transfering large amount of // data. See Microsoft KB article KB823764. // if(_maxSendPacketSize > 0 && packetSize > _maxSendPacketSize / 2) { packetSize = _maxSendPacketSize / 2; } } int sent = 0; while(buf.hasRemaining()) { try { int ret = _fd.Send(buf.rawBytes(), buf.position(), packetSize, SocketFlags.None); Debug.Assert(ret > 0); sent += ret; buf.position(buf.position() + ret); if(packetSize > buf.remaining()) { packetSize = buf.remaining(); } } catch(SocketException ex) { if(Network.wouldBlock(ex)) { return sent; } else if(Network.connectionLost(ex)) { throw new Ice.ConnectionLostException(ex); } throw new Ice.SocketException(ex); } } return sent; }
private int read(ByteBuffer buf) { Debug.Assert(_fd != null); int read = 0; while(buf.hasRemaining()) { try { int ret = _fd.Receive(buf.rawBytes(), buf.position(), buf.remaining(), SocketFlags.None); if(ret == 0) { throw new Ice.ConnectionLostException(); } read += ret; buf.position(buf.position() + ret); } catch(SocketException ex) { if(Network.wouldBlock(ex)) { return read; } else if(Network.interrupted(ex)) { continue; } else if(Network.connectionLost(ex)) { throw new Ice.ConnectionLostException(ex); } throw new Ice.SocketException(ex); } } return read; }