Parses a given Range header for one or more byte ranges.

@param rangeHeader    Range header to parse
@param resourceLength Length of the resource in bytes
@return List of parsed ranges
425245
private List<ByteRange> parseRangeHeader(final String rangeHeader, final int resourceLength) {
        final List<ByteRange> byteRanges;
        if (rangeHeader.contains("=")) {
            final String[] parts = rangeHeader.split("=", -1);
            if (parts.length > 1) {
                byteRanges = Arrays.stream(parts[1].split(",", -1))
                        .map(String::trim)
                        .map(s -> ByteRange.parse(s, resourceLength))
                        .collect(Collectors.toList());
            } else {
                byteRanges = Collections.emptyList();
            }
        } else {
            byteRanges = Collections.emptyList();
        }
        return byteRanges;
    }
1017020
public static long length(final Range<Long> range) {
        checkClosedOpen(range);
        return Math.max(0L, range.upperEndpoint() - range.lowerEndpoint());
    }
728681
public void writeHeaders(HttpResponse response,Resource resource, long count)
        throws IOException
    {
        ResourceCache.ResourceMetaData metaData =
            (ResourceCache.ResourceMetaData)resource.getAssociate();

        response.setContentType(metaData.getMimeType());
        if (count != -1)
        {
            if (count==resource.length())
                response.setField(HttpFields.__ContentLength,metaData.getLength());
            else
                response.setContentLength((int)count);
        }

        response.setField(HttpFields.__LastModified,metaData.getLastModified());
        
        if (_acceptRanges && response.getHttpRequest().getDotVersion()>0)
            response.setField(HttpFields.__AcceptRanges,"bytes");
    }
215215
private Header[] getLinkHeaders(final String resourceUri) throws IOException {
        final HttpHead request = new HttpHead(resourceUri);
        final HttpResponse response = httpClient.execute(request);
        LOGGER.debug("Got: " + response.getStatusLine().getStatusCode() + " for HEAD " + resourceUri);
        return response.getHeaders("Link");
    }
248699
public static ByteRange parse(String rangeHeader) {
        if(rangeHeader == null || rangeHeader.length() < 7) {
            return null;
        }
        if(!rangeHeader.startsWith("bytes=")) {
            return null;
        }
        List<Range> ranges = new ArrayList<>();
        String[] parts = rangeHeader.substring(6).split(",");
        for(String part : parts) {
            try {
                int index = part.indexOf('-');
                if (index == 0) {
                    //suffix range spec
                    //represents the last N bytes
                    //internally we represent this using a -1 as the start position
                    long val = Long.parseLong(part.substring(1));
                    if(val < 0) {
                        UndertowLogger.REQUEST_LOGGER.debugf("Invalid range spec %s", rangeHeader);
                        return null;
                    }
                    ranges.add(new Range(-1, val));
                } else {
                    if(index == -1) {
                        UndertowLogger.REQUEST_LOGGER.debugf("Invalid range spec %s", rangeHeader);
                        return null;
                    }
                    long start = Long.parseLong(part.substring(0, index));
                    if(start < 0) {
                        UndertowLogger.REQUEST_LOGGER.debugf("Invalid range spec %s", rangeHeader);
                        return null;
                    }
                    long end;
                    if (index + 1 < part.length()) {
                        end = Long.parseLong(part.substring(index + 1));
                    } else {
                        end = -1;
                    }
                    ranges.add(new Range(start, end));
                }
            } catch (NumberFormatException e) {
                UndertowLogger.REQUEST_LOGGER.debugf("Invalid range spec %s", rangeHeader);
                return null;
            }
        }
        if(ranges.isEmpty()) {
            return null;
        }
        return new ByteRange(ranges);
    }
753284
@Override
	public void parseHeader(String header, S sequence) {
		sequence.setOriginalHeader(header);
		String[] data = getHeaderValues(header);

		if (data.length == 1) {
			sequence.setAccession(new AccessionID(data[0]));
		} else {
			throw new RuntimeException(
					"No header or Some Error Occurred while reading header");
		}
	}
1052435
public List<String> sortedHeader(@NotNull final String header) {
        String accept = getHeader(header);
        // accept anything when accept is not present
        if (accept == null) {
            return Collections.emptyList();
        }

        // parse
        String[] items = accept.split(" *, *");
        // sort on quality
        Arrays.sort(items, ACCEPT_X_COMPARATOR);

        List<String> list = new ArrayList<>(items.length);

        for (String item : items) {
            // find any ; e.g.: "application/json;q=0.8"
            int space = item.indexOf(';');

            if (space != -1) {
                list.add(item.substring(0, space));
            } else {
                list.add(item);
            }
        }

        return list;
    }
463952
def set_range(r, e = nil)
      unless r
        @header.delete 'range'
        return r
      end
      r = (r...r+e) if e
      case r
      when Numeric
        n = r.to_i
        rangestr = (n > 0 ? "0-#{n-1}" : "-#{-n}")
      when Range
        first = r.first
        last = r.last
        last -= 1 if r.exclude_end?
        if last == -1
          rangestr = (first > 0 ? "#{first}-" : "-#{-first}")
        else
          raise HTTPHeaderSyntaxError, 'range.first is negative' if first < 0
          raise HTTPHeaderSyntaxError, 'range.last is negative' if last < 0
          raise HTTPHeaderSyntaxError, 'must be .first < .last' if first > last
          rangestr = "#{first}-#{last}"
        end
      else
        raise TypeError, 'Range/Integer is required'
      end
      @header['range'] = ["bytes=#{rangestr}"]
      r
    end
994760
private static void _parseHeaderLine (@Nonnull final FileItemHeaders aHeaders, @Nonnull final String sHeader)
  {
    final int nColonOffset = sHeader.indexOf (':');
    if (nColonOffset == -1)
    {
      // This header line is malformed, skip it.
      if (LOGGER.isWarnEnabled ())
        LOGGER.warn ("Found malformed HTTP header line '" + sHeader + "'");
      return;
    }
    final String sHeaderName = sHeader.substring (0, nColonOffset).trim ();
    final String sHeaderValue = sHeader.substring (sHeader.indexOf (':') + 1).trim ();
    aHeaders.addHeader (sHeaderName, sHeaderValue);
  }
1372529
public IdRange[] parseIdRange(ImapRequestLineReader request)
            throws ProtocolException {
        CharacterValidator validator = new MessageSetCharValidator();
        String nextWord = consumeWord(request, validator);

        int commaPos = nextWord.indexOf(',');
        if (commaPos == -1) {
            return new IdRange[]{IdRange.parseRange(nextWord)};
        }

        List<IdRange> rangeList = new ArrayList<>();
        int pos = 0;
        while (commaPos != -1) {
            String range = nextWord.substring(pos, commaPos);
            IdRange set = IdRange.parseRange(range);
            rangeList.add(set);

            pos = commaPos + 1;
            commaPos = nextWord.indexOf(',', pos);
        }
        String range = nextWord.substring(pos);
        rangeList.add(IdRange.parseRange(range));
        return rangeList.toArray(new IdRange[rangeList.size()]);
    }
1004580
public static Map<String, List<String>> getResponseHeaders(String stringUrl,
      boolean followRedirects) throws IOException {
    URL url = new URL(stringUrl);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setInstanceFollowRedirects(followRedirects);
    
    InputStream is = conn.getInputStream();
    if ("gzip".equals(conn.getContentEncoding())) {
       is = new GZIPInputStream(is);
    }

    Map<String, List<String>> headers = new LinkedHashMap<String, List<String>>(conn.getHeaderFields());
    headers.put("X-Content", Arrays.asList(MyStreamUtils.readContent(is)));
    headers.put("X-URL", Arrays.asList(conn.getURL().toString()));
    headers.put("X-Status", Arrays.asList(String.valueOf(conn.getResponseCode())));
    
    return headers;
  }
753917
protected final boolean parseHeaders(ByteBuffer in) throws BaseExceptions.BadMessage, BaseExceptions.InvalidState {

        headerLoop: while (true) {
            char ch;
            switch (_hstate) {
                case START:
                    _hstate = HeaderState.HEADER_IN_NAME;
                    resetLimit(headerSizeLimit);

                case HEADER_IN_NAME:
                    for(ch = next(in, false); ch != ':' && ch != HttpTokens.LF; ch = next(in, false)) {
                        if (ch == HttpTokens.EMPTY_BUFF) return false;
                        putChar(ch);
                    }

                    // Must be done with headers
                    if (bufferPosition() == 0) {
                        _hstate = HeaderState.END;

                        // Finished with the whole request
                        if (_chunkState == ChunkState.CHUNK_TRAILERS) {
                            shutdownParser();
                        }
                        else if ((_endOfContent == EndOfContent.UNKNOWN_CONTENT && mustNotHaveBody())) {
                            shutdownParser();
                        }

                        // Done parsing headers
                        return true;
                    }

                    if (ch == HttpTokens.LF) {  // Valueless header
                        String name = getString();
                        clearBuffer();

                        if (headerComplete(name, "")) {
                            return true;
                        }

                        continue headerLoop;    // Still parsing Header name
                    }

                    _headerName = getString();
                    clearBuffer();
                    _hstate = HeaderState.HEADER_IN_VALUE;

                case HEADER_IN_VALUE:
                    for(ch = next(in, true); ch != HttpTokens.LF; ch = next(in, true)) {
                        if (ch == HttpTokens.EMPTY_BUFF) return false;
                        putChar(ch);
                    }

                    String value;
                    try { value = getTrimmedString(); }
                    catch (BaseExceptions.BadMessage e) {
                        shutdownParser();
                        throw e;
                    }
                    clearBuffer();

                    // If we are not parsing trailer headers, look for some that are of interest to the request
                    if (_chunkState != ChunkState.CHUNK_TRAILERS) {
                        if (_headerName.equalsIgnoreCase("Transfer-Encoding")) {
                            if (value.equalsIgnoreCase("chunked")) {
                                // chunked always overrides Content-Length
                                if (_endOfContent != EndOfContent.END) {
                                    _endOfContent = EndOfContent.CHUNKED_CONTENT;
                                }
                            } else if (value.equalsIgnoreCase("identity")) {
                                // TODO: remove support for identity Transfer-Encoding.
                                // It  was removed from the specification before it was published 
                                // (althoug some traces of it remained until errata was released: 
                                // http://lists.w3.org/Archives/Public/ietf-http-wg-old/2001SepDec/0018.html
                                // if (_endOfContent == EndOfContent.UNKNOWN_CONTENT) {
                                //     _endOfContent = EndOfContent.EOF_CONTENT; 
                                // }
                            }
                            else {
                                shutdownParser();
                                // TODO: server should return 501 - https://tools.ietf.org/html/rfc7230#page-30
                                throw new BadMessage("Unknown Transfer-Encoding: " + value);
                            }
                        }
                        else if (_endOfContent != EndOfContent.CHUNKED_CONTENT && _headerName.equalsIgnoreCase("Content-Length")) {
                            try {
                                long len = Long.parseLong(value);
                                if ((_endOfContent == EndOfContent.NO_CONTENT || 
                                     _endOfContent == EndOfContent.CONTENT_LENGTH) && len != _contentLength) {
                                    // Multiple different Content-Length headers are an error
                                    // https://tools.ietf.org/html/rfc7230#page-31
                                    long oldLen = _contentLength;
                                    shutdownParser();
                                    throw new BadMessage("Duplicate Content-Length headers detected: " +
                                                         oldLen + " and " + len + "\n");
                                }
                                else if (len > 0) {
                                    _contentLength = len;
                                    _endOfContent = EndOfContent.CONTENT_LENGTH;
                                }
                                else if (len == 0) {
                                    _contentLength = len;
                                    _endOfContent = EndOfContent.NO_CONTENT;
                                }
                                else { // negative content-length
                                    shutdownParser();
                                    throw new BadMessage("Cannot have negative Content-Length: '" + len + "'\n");
                                }
                            }
                            catch (NumberFormatException t) {
                                shutdownParser();
                                throw new BadMessage("Invalid Content-Length: '" + value + "'\n");
                            }
                        }
                    }

                    // Send off the header and see if we wish to continue
                    try {
                        if (headerComplete(_headerName, value)) {
                            return true;
                        }
                    } finally {
                        _hstate = HeaderState.HEADER_IN_NAME;
                    }

                    break;

                case END:
                    shutdownParser();
                    throw new InvalidState("Header parser reached invalid position.");
            }   // Switch
        }   // while loop
    }
1089335
def parse_range_header(header, maxlen=0):
    ''' '''
    if not header or header[:6] != 'bytes=': return
    ranges = [r.split('-', 1) for r in header[6:].split(',') if '-' in r]
    for start, end in ranges:
        try:
            if not start:  # bytes=-100    -> last 100 bytes
                start, end = max(0, maxlen-int(end)), maxlen
            elif not end:  # bytes=100-    -> all but the first 99 bytes
                start, end = int(start), maxlen
            else:          # bytes=100-200 -> bytes 100-200 (inclusive)
                start, end = int(start), min(int(end)+1, maxlen)
            if 0 <= start < end <= maxlen:
                yield start, end
        except ValueError:
            pass
800369
public static long[][] getRange(Map<String, String> headers) {
		String rangeValue = getHeaderValue(headers, HTTP_RANGE_HEADER_UP);
		if (rangeValue == null) return null;
		rangeValue = rangeValue.trim();
		return parseRanges(rangeValue);
	}
1227300
private static Map<String, String> getHeaderParams( final String header ) {
        if( header == null || header.length() == 0 )
            return Collections.emptyMap();

        final int headerLength = header.length();
        int start = header.indexOf(';') + 1;
        if( start == 0 || start == headerLength )
            return Collections.emptyMap();

        int end = header.indexOf(';', start);
        if( end == -1 )
            end = headerLength;

        Map<String, String> params = new LinkedHashMap<String, String>();
        while( start < end ) {
            int nameEnd = header.indexOf('=', start);
            if( nameEnd != -1 && nameEnd < end ) {
                String name = header.substring(start, nameEnd).trim();
                if( name.length() > 0 ) {
                    String value = header.substring(nameEnd + 1, end).trim();
                    int length = value.length();
                    if( length != 0 )
                        if( length > 2 && '"' == value.charAt(0) && '"' == value.charAt(length - 1) )
                            params.put(name, value.substring(1, length - 1));
                        else
                            params.put(name, value);
                }
            }

            start = end + 1;
            end = header.indexOf(';', start);
            if( end == -1 )
                end = headerLength;
        }

        return params;
    }
407763
private static List<Integer> parseRange(String range, int max) {
        List<Integer> idx = new ArrayList<Integer>();
        String[] n = range.split(",");
        for (String s : n) {
            String[] d = s.split("-");
            int mi = Integer.parseInt(d[0]);
            if (mi < 0 || mi >= max) {
                throw new IllegalArgumentException(range);
            }
            if (d.length == 2) {
                if (d[1].equals("*")) {
                    d[1] = Integer.toString(max - 1);
                }
                int ma = Integer.parseInt(d[1]);
                if (ma <= mi || ma >= max || ma < 0) {
                    throw new IllegalArgumentException(range);
                }
                for (int i = mi; i <= ma; i++) {
                    idx.add(i);
                }
            } else {
                idx.add(mi);
            }
        }
        return idx;
    }
147928
static void parseHeader(final String header, Map<Token, String> response) {
        if (response.size() == Token.values().length) {
            //already parsed everything
            return;
        }
        char[] headerChars = header.toCharArray();

        SearchingFor searchingFor = SearchingFor.START_OF_NAME;
        int nameStart = 0;
        Token currentToken = null;
        int valueStart = 0;

        int escapeCount = 0;
        boolean containsEscapes = false;

        for (int i = 0; i < headerChars.length; i++) {
            switch (searchingFor) {
                case START_OF_NAME:
                    // Eliminate any white space before the name of the parameter.
                    if (headerChars[i] != ';' && !Character.isWhitespace(headerChars[i])) {
                        nameStart = i;
                        searchingFor = SearchingFor.EQUALS_SIGN;
                    }
                    break;
                case EQUALS_SIGN:
                    if (headerChars[i] == '=') {
                        String paramName = String.valueOf(headerChars, nameStart, i - nameStart);
                        currentToken = TOKENS.get(paramName.toLowerCase(Locale.ENGLISH));
                        //we allow unkown tokens, but just ignore them
                        searchingFor = SearchingFor.START_OF_VALUE;
                    }
                    break;
                case START_OF_VALUE:
                    if (!Character.isWhitespace(headerChars[i])) {
                        if (headerChars[i] == '"') {
                            valueStart = i + 1;
                            searchingFor = SearchingFor.LAST_QUOTE;
                        } else {
                            valueStart = i;
                            searchingFor = SearchingFor.END_OF_VALUE;
                        }
                    }
                    break;
                case LAST_QUOTE:
                    if (headerChars[i] == '\\') {
                        escapeCount++;
                        containsEscapes = true;
                    } else if (headerChars[i] == '"' && (escapeCount % 2 == 0)) {
                        String value = String.valueOf(headerChars, valueStart, i - valueStart);
                        if (containsEscapes) {
                            StringBuilder sb = new StringBuilder();
                            boolean lastEscape = false;
                            for (int j = 0; j < value.length(); ++j) {
                                char c = value.charAt(j);
                                if (c == '\\' && !lastEscape) {
                                    lastEscape = true;
                                } else {
                                    lastEscape = false;
                                    sb.append(c);
                                }
                            }
                            value = sb.toString();
                            containsEscapes = false;
                        }
                        if (currentToken != null && !response.containsKey(currentToken)) {
                            response.put(currentToken, value);
                        }

                        searchingFor = SearchingFor.START_OF_NAME;
                        escapeCount = 0;
                    } else {
                        escapeCount = 0;
                    }
                    break;
                case END_OF_VALUE:
                    if (headerChars[i] == ';' || headerChars[i] == ',' || Character.isWhitespace(headerChars[i])) {
                        String value = String.valueOf(headerChars, valueStart, i - valueStart);
                        if (currentToken != null && !response.containsKey(currentToken)) {
                            response.put(currentToken, value);
                        }

                        searchingFor = SearchingFor.START_OF_NAME;
                    }
                    break;
            }
        }

        if (searchingFor == SearchingFor.END_OF_VALUE) {
            // Special case where we reached the end of the array containing the header values.
            String value = String.valueOf(headerChars, valueStart, headerChars.length - valueStart);
            if (currentToken != null && !response.containsKey(currentToken)) {
                response.put(currentToken, value);
            }
        } else if (searchingFor != SearchingFor.START_OF_NAME) {
            // Somehow we are still in the middle of searching for a current value.
            throw MESSAGES.invalidHeader();
        }

    }